// // main // int main(int argc, char **argv) { dbCursor<LibM> cursor1; if (argc != 4) { printf("Usage: %s target lib_root_path full:0|1\n", argv[0]); return 0; } lib_root_path = argv[2]; bFull = argv[3][0] == '1'; TCHAR *filename = argv[1]; TCHAR filename2[MAX_PATH]; int i; DeleteFile("LibM.fdb"); if (!db.open("LibM")) { return 0; } printf("Built on " __DATE__ " " __TIME__ "\nInit db..."); build_instruction_db(); printf("total:%d OK\n", lib_count); //getch(); InitializeCriticalSection(&cs); while (1) { printf("Loading...\n"); if (!LoadFileR(filename, &stMapFile)) { cerr << "ERROR FILE!" << endl; //continue; break; } if (!IsPEFile(stMapFile.ImageBase)) { cerr << "NOT PE FILE!" << endl; UnLoadFile(&stMapFile); //continue; break; } pOH = GetOptionalHeader(stMapFile.ImageBase); pImageNtH = GetNtHeaders(stMapFile.ImageBase); int c0 = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0, count = 0; // read target function info wsprintf(filename2, _T("%s.txt"), filename); ifstream is2(filename2, ios::binary); if (!is2.is_open()) { break; } int tt; db.detach(); f_info.clear(); while (!is2.eof()) { int startEA, endEA; is2.read((char *)&startEA, sizeof(int)); is2.read((char *)&endEA, sizeof(int)); if (endEA - startEA < MIN_INS_LENGTH) { continue; } function_info fi; memset(&fi, 0, sizeof(fi)); fi.startEA = startEA; fi.len = endEA - startEA; fi.lib_name[0] = 0; f_info.push_back(fi); } total_function_len = f_info.size(); //sort(f_info.begin(), f_info.end(), myfunction); printf("OK\n"); tt = GetTickCount(); int thread_num = bMultiThread ? THREAD_NUM : 1; if (show_dump) { thread_num = 1; } HANDLE *thread = new HANDLE[thread_num]; for (i = 0; i < thread_num; i++) { thread[i] = (HANDLE)_beginthreadex(NULL, 0, bFull ? (&MatchThreadForFull) : (&MatchThread), (void *)i, 0, NULL); } WaitForMultipleObjects(thread_num, thread, TRUE, INFINITE); tt = GetTickCount() - tt; delete[] thread; db.attach(); UnLoadFile(&stMapFile); if (cursor1.select() > 0) { do { delete (ControlFlowGraph *)cursor1->cfg; } while (cursor1.next()); } DWORD s = 0; DWORD _r0 = 0, _r1 = 0, _r34 = 0, _r2 = 0, _r5 = 0, _fn = 0; for (i = 0; i < THREAD_NUM; i++) { s += instruction_count[i]; _r0 += r0[i]; _r1 += r1[i]; _r2 += r2[i]; _r34 += r34[i]; _r5 += r5[i]; _fn += fn[i]; } printf("#fn:%d #instr:%d t:%d found:%d\n", _fn, s, tt, found_c); printf("r1:\t%d\n", _r1); printf("r2:\t%d\n", _r2); printf("r34:\t%d\n", _r34); printf("r5:\t%d\n", _r5); printf("r0:\t%d\n", _r0); printf("fulled:\t%d\n", fulled); printf("check failed:\t%d\n", check_failed); printf("END.\n"); break; } DeleteCriticalSection(&cs); db.detach(); #ifdef _DEBUG cout << "Press ENTER..." << endl; char c; c = cin.get(); #endif return 0; }
BOOL CodeInject() { PROCESS_INFORMATION pi; STARTUPINFO sif = { 0, }; HANDLE hFile = NULL , hFileMap = NULL, hShare = NULL; PVOID Base, ShareBase; HMODULE hMod; PFNLOADLIBRARY pfnLoadLibrary; PIMAGE_OPTIONAL_HEADER ioh; DWORD EntryPoint; DWORD CodeSize; DWORD offset; BYTE* Buffer = NULL; DATA sendData; char code[] = { 0x6A, 0x6C, 0x68, 0x79, 0x2E, 0x64, 0x6C, 0x68, 0x64, 0x75, 0x6D, 0x6D, 0x8B, 0xC4, 0x50, 0xE8, 0xFC, 0x46, 0xA2, 0xFE, 0x8B, 0xE5, 0x5D }; sif.cb = sizeof(STARTUPINFO); CodeSize = sizeof(code); //#1. 타겟파일 포인터를 획득한다. hFile = CreateFile(L"TEST.exe", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return false; hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (hFileMap == NULL) goto $cleanup; Base = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, NULL); if (!Base) goto $cleanup; //#2. 덮어쓸 코드섹션을 복사한다. ioh = GetOptionalHeader(Base); if (!ioh->Magic == 0x10b || !ioh->Magic == 0x20b) { printf("GetOptionalHeader error\n"); return false; } EntryPoint = (DWORD)RvaToRaw(Base, ioh->AddressOfEntryPoint); Buffer = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_NO_SERIALIZE, CodeSize); memcpy(Buffer, (PVOID)EntryPoint, CodeSize); //#3. 타겟쓰레드를 resume으로 생성한다. if (!CreateProcess(L"TEST.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sif, &pi)) { UnmapViewOfFile(ShareBase); CloseHandle(hShare); goto $cleanup; } //#4. dll인젝션한다. //#5. dll에서작업이 끝났는지확인한다. //#6. 원본코드를 덮어쓴다. //#7. 쓰레드를 resume시킨다. ResumeThread(pi.hThread); $cleanup: if (!hFileMap) CloseHandle(hFile); if (!Base) CloseHandle(hFileMap); if (!hShare) HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, Buffer); }