***第一个递归问题解决了,原因是如果加载过的dll再修复一边会重复包含然后卡死循环,不过后来有大佬告诉我LoadLibrary或自动加载所需要的DLL,所以竹篮打水一场空,不过我还是会修改代码的,给大家演示一下这种情况,说不定未来哪天能用上
但是就算解决了也无法运行图形界面的程序,比如飞鸽运行出来没有图标,界面只有一个后台进程,PEtool跑不了
后来都要学完内核了,才想起来了,这个软件跑不起来才是正常的,傀儡进程能跑起来图形界面,是因为创建了一个新的进程并且有自己的界面,控制台程序已经占有了这个线程
第一个跳转这个没写好,只有能加载控制台程序,我猜是导入表dll依赖其他dll,那么就需要递归,但我怎么也写不出来,那个递归莫名其妙的有个死循环,一直重复包含
后面贴了IAT修复函数,里面有写一个坑,修复IAT的时候注意对着INT修改成IAT,因为后面那个程序的IAT是已经被修过的了,没有储存数据
VOID ProcessJmp(PBYTE pFileName) {
//读入数据,初始化各项需要的数据
PBYTE pFileBuffer = 0;
PBYTE pImageBuffer = 0;
DWORD dwFileSize = FileToFileBuffer(pFileName, &pFileBuffer);
DWORD dwImageSize = FileBufferToImageBuffer(pFileBuffer, &pImageBuffer, dwFileSize);
free(pFileBuffer);
PIMAGE_DOS_HEADER pDosHeader = pImageBuffer;
PIMAGE_NT_HEADERS pNTHeader = (DWORD)pImageBuffer + pDosHeader->e_lfanew;
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
printf("File is not PE\n");
free(pImageBuffer);
return FALSE;
}
PIMAGE_FILE_HEADER pFileHeader = (DWORD)pNTHeader + sizeof(pNTHeader->Signature);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
PIMAGE_SECTION_HEADER pSectionHeader = (DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader;
PBYTE oep = pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint;
//在自身内存Process.ImageBase处申请Process.ImageSize大小的内存
HANDLE hCurProcess = GetCurrentProcess();
PVOID pImageBase = VirtualAllocEx(hCurProcess, pOptionalHeader->ImageBase, pOptionalHeader->SizeOfImage,
MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pImageBase) {
printf("VirtualAllocEx1\n");
return;
}
//修IAT
FixIATTable(&pImageBuffer);
//写入pImageBase处
if (!WriteProcessMemory(hCurProcess, pImageBase, pImageBuffer, dwImageSize, 0)) {
printf("WriteProcessMemory\n");
return;
}
free(pImageBuffer);
__asm {
jmp oep
}
}
VOID __stdcall Entry(LPVOID pImageBase) {
//修复IAT表
FixIATTable(&pImageBase);
MessageBoxA(0, "Hello", 0, 0);
}
//进程注入
VOID ProcessInject(PBYTE pFileName){
//数据初始化
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi;
HANDLE hCurProcess = GetCurrentProcess();
HMODULE hModule = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pNtHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
PIMAGE_OPTIONAL_HEADER pOptionHeader = &pNtHeader->OptionalHeader;
PBYTE dwImageBase = hModule;
DWORD dwSizeOfImage = pOptionHeader->SizeOfImage;
//内存处理
PBYTE pCurImage = (PBYTE)malloc(dwSizeOfImage);
if (!pCurImage) {
printf("malloc1\n");
return;
}
if (!ReadProcessMemory(hCurProcess, dwImageBase, pCurImage, dwSizeOfImage, 0)) {
free(pCurImage);
printf("ReadProcessMemory\n");
return;
}
pDosHeader = (PIMAGE_DOS_HEADER)pCurImage;
pNtHeader = (DWORD)pDosHeader + pDosHeader->e_lfanew;
pOptionHeader = &pNtHeader->OptionalHeader;
PIMAGE_BASE_RELOCATION pBaseRelocation =
pOptionHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + pCurImage;
if (!CreateProcessA(pFileName, 0, 0, 0, 0, CREATE_NEW_CONSOLE, 0, 0, &si, &pi)) {
printf("CreateProcessA\n");
return;
}
PBYTE pNewImageBase = VirtualAllocEx(pi.hProcess, 0, dwSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!pNewImageBase) {
printf("VirtualAllocEx\n");
return;
}
pOptionHeader->ImageBase = pNewImageBase;
//修复重定位表
DWORD dwImageDiff = pNewImageBase - dwImageBase;
if (pBaseRelocation != pCurImage) {
while (pBaseRelocation->VirtualAddress && pBaseRelocation->SizeOfBlock) {
DWORD items = (pBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
PWORD pBlock = (DWORD)pBaseRelocation + sizeof(IMAGE_BASE_RELOCATION);
for (size_t i = 0; i < items; i++) {
if (*pBlock >> 12) {
DWORD VA = pBaseRelocation->VirtualAddress + (*pBlock & 0xfff);
PDWORD offsetAddr = (PDWORD)(VA + pCurImage);
//printf("%x %x\n", VA, *offsetAddr);
*((PDWORD)(VA + pCurImage)) += dwImageDiff;
}
pBlock++;
}
pBaseRelocation = (DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock;
}
}
else {
printf("no base relocation table\n");
}
//写入新建进程中,再创建线程运行
if (!WriteProcessMemory(pi.hProcess, pNewImageBase, pCurImage, dwSizeOfImage, 0)) {
printf("WriteProcessMemory\n");
return;
}
free(pCurImage);
DWORD entryAddr = (DWORD)Entry + dwImageDiff;
HANDLE hRemoteThread = CreateRemoteThread(pi.hProcess, 0, 0, entryAddr,pNewImageBase, 0, 0);
if (!hRemoteThread) {
printf("CreateRemoteThread");
return;
}
WaitForSingleObject(hRemoteThread, INFINITE);
//CloseHandle(hRemoteThread);
}
//修复IAT表,递归导入互相依赖的dll(实现了)
VOID FixIATTable(PVOID* pImageBufferBuffer) {
//MessageBoxA(0, 0, 0, 0);
PBYTE pImageBuffer = *pImageBufferBuffer;
PIMAGE_DOS_HEADER pDosHeader = pImageBuffer;
PIMAGE_NT_HEADERS pNTHeader = (DWORD)pImageBuffer + pDosHeader->e_lfanew;
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) {
printf("File is not PE\n");
free(pImageBuffer);
return;
}
PIMAGE_FILE_HEADER pFileHeader = (DWORD)pNTHeader + sizeof(pNTHeader->Signature);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = (DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER);
if (!pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) {
//printf("No import table\n");
return;
}
PIMAGE_IMPORT_DESCRIPTOR pImportTable =
pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + pImageBuffer;
while (pImportTable->OriginalFirstThunk) {
//大坑,不要乱用函数,因为还没有加载过...
BOOL flag = 0;
PBYTE lpDllName = pImportTable->Name + pImageBuffer;
//printf("%s\n", lpDllName);
HANDLE hModule = GetModuleHandleA(lpDllName);
if (!hModule) {
hModule = LoadLibraryA(lpDllName);
flag = 1;
if (!hModule) {
//printf("hModule获取失败\n");
return;
}
}
PDWORD pINT = pImportTable->OriginalFirstThunk + pImageBuffer;
PDWORD pIAT = pImportTable->FirstThunk + pImageBuffer;
while (*pINT) {
PVOID pFunAddr;
if (*pINT & 0x80000000) {
pFunAddr = GetProcAddress(hModule, *pINT & 0x7fffffff);
//printf("pImportByOrdinals:%x\n", *pINT & 0x7fffffff);
}
else {
PIMAGE_IMPORT_BY_NAME pImportByName = *pINT + pImageBuffer;
//printf("pImportByName:%s\n", pImportByName->Name);
pFunAddr = GetProcAddress(hModule, pImportByName->Name);
}
DWORD dwProtect;
if (!VirtualProtectEx(-1, pIAT, sizeof(PVOID), PAGE_READWRITE, &dwProtect)) {
printf("VirtualProtect");
return;
}
*pIAT = pFunAddr;
pIAT++;
pINT++;
}
if (flag){
//如果不想用递归就加个注释就能跑了
FixIATTable(&hModule);
}
pImportTable++;
}
}