赞
踩
找文章看了一下, 讲的很好, 但是地址没了…尴尬, 03年的技术, 大致内容就是介绍了两种注入技术, 一个为常规的远程线程注入, 另一个就是内存注入. 只不过文章思路是只插入一段代码, 也就是编写shellcode. 而无模块注入则是将模块整体以内存写入的形式加载实现隐藏 .
杀软依然秒杀…但是我封装起来写后就检测不到, 特征码竟然消失了…
思路是将自己复制一份加载到目标进程中, 即注入进程和寄生程序是一个东西.不过想想也知道, 注入dll也是一个原理, 无非是拉伸之后再贴到目标进程, 最后依然是起远程线程设置入口点.
但重点在于, 寄生程序IAT中的地址与目标进程的地址可能不一致, 或者没有加载相关dll, 这个时候就要根据目标进程的IAT修复寄生进程的IAT.
在写这个的时候遇到了一些问题如下:
实在是过于麻烦了…带着这个问题, 我们找到了如下答案
https://bbs.pediy.com/thread-259087.htm
又因为每个程序都用到了LoadLibrary和GetProcAddress那么就可以放心大胆的用了.
此时进入目标进程, 线程函数首先需要修复IAT表, 绝对要注意, 进入了线程函数之后修复IAT之前, 当然包括修复IAT都不可以使用非系统必要dll的函数.
给出主体与修复重定位和IAT表的代码
//通过GetCurrent得到的句柄是假句柄, 只对当前进程有用, 无需CloseHandle; //获取自身Buffer, 当然这里完全可以换成从文件读一个dll然后展开注入, 思路一样 Process::GetProcInfo(&curPi); sizeOfImage = Pe::GetSizeOfImage(::GetModuleHandleA(NULL)); pImageBuffer = malloc(sizeOfImage); memcpy(pImageBuffer, ::GetModuleHandleA(NULL),sizeOfImage); //申请空间 hostPi.hProcess = Process::OpenProcessM(hostName); if (!(allocBaseAddr = Process::VirtualAllocate( hostPi.hProcess, NULL, sizeOfImage, PAGE_EXECUTE_READWRITE ))) return NULL; //可能出现无重定位的exe, 直接返回失败 if (!Pe::RebaseRelocation(pImageBuffer, (DWORD)allocBaseAddr)) { ::VirtualFreeEx(hostPi.hProcess, allocBaseAddr, NULL, MEM_RELEASE); return NULL; } //写入修复重定位的Buffer, 并计算起始地址开远程线程 ::WriteProcessMemory(hostPi.hProcess, allocBaseAddr, pImageBuffer, sizeOfImage, NULL); crtStartUp = (LPTHREAD_START_ROUTINE)((DWORD)allocBaseAddr + (DWORD)injectThread - (DWORD)GetModuleHandle(NULL)); hostPi.hThread = ::CreateRemoteThread( hostPi.hProcess, NULL, NULL, crtStartUp, allocBaseAddr, NULL, NULL); //释放句柄, 栈空间 ::WaitForSingleObject(hostPi.hThread, INFINITE); //如果为完全释放, 大小必须为空, 系统会按照分配时的大小释放空间 ::VirtualFreeEx(hostPi.hProcess, allocBaseAddr, NULL, MEM_RELEASE); free(pImageBuffer); Process::CloseHandles(hostPi);
void InjectFunc() { char szTemp[256] = { 0 }; printf("测试程序..如果IAT未修复则无法运行.\n"); //这两行程序可以测试IAT是否修复成功, 字符串初始化操作调用memset for (int i = 0; i < 3; i++) MessageBoxA(0, 0, "注入成功", 0); } DWORD WINAPI ThreadProc(LPVOID lparams) { if (!Pe::RestoreIAT(lparams)) { MessageBoxA(NULL, NULL, "修复重定位失败!", NULL); return -1; } InjectFunc(); return 1; } int main() { CHAR hostName[] = "demo.exe"; injector::InjectThrowMemory(hostName, (LPTHREAD_START_ROUTINE)(ThreadProc)); printf("内存注入线程结束, 任意键退出.\n"); system("pause"); return 0; }
PIMAGE_NT_HEADERS Pe::GetNtHeaders(LPVOID pBuffer) { return (PIMAGE_NT_HEADERS)((DWORD)pBuffer + *((DWORD*)((DWORD)(pBuffer)+0x3c))); } BOOL Pe::RebaseRelocation(LPVOID pImageBuffer, DWORD newImageBase) { DWORD rvaBaseRelocation = 0; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; PIMAGE_BASE_RELOCATION pBaseRelocation = NULL; PIMAGE_NT_HEADERS pNtHeaders = NULL; pNtHeaders = GetNtHeaders(pImageBuffer); pDataDirectory = pNtHeaders->OptionalHeader.DataDirectory; rvaBaseRelocation = (*(pDataDirectory + 5)).VirtualAddress; if (!rvaBaseRelocation) { MessageBoxA(NULL, "软件无重定位!!! 无法更改ImageBase", "Error", NULL); return FALSE; } pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pImageBuffer + rvaBaseRelocation); DWORD foaOfData = 0; DWORD rvaOfData = 0; DWORD currentBlockItems = 0; DWORD foaOfBlock = 0; DWORD differenceOfImageBase = 0; DWORD addressOf_rvaOfData = 0; DWORD* pFarAddress = NULL; differenceOfImageBase = newImageBase - pNtHeaders->OptionalHeader.ImageBase; pNtHeaders->OptionalHeader.ImageBase = newImageBase; while (pBaseRelocation->SizeOfBlock) { //要修改的数据大表在文件中的偏移 大表 + word 型偏移 foaOfBlock = (DWORD)pBaseRelocation - (DWORD)pImageBuffer; currentBlockItems = (pBaseRelocation->SizeOfBlock - 8) / 2; //word 表示 addressOf_rvaOfData = pBaseRelocation->VirtualAddress; while (--currentBlockItems) { rvaOfData = ((*(WORD*)(foaOfBlock + (DWORD)pImageBuffer + 8)) & 0x0fff) + addressOf_rvaOfData; pFarAddress = (DWORD*)(rvaOfData + (DWORD)pImageBuffer); *pFarAddress += differenceOfImageBase; foaOfBlock += 2; } pBaseRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pBaseRelocation + pBaseRelocation->SizeOfBlock); } return TRUE; } BOOL Pe::RestoreIAT(LPVOID pImageBuffer) { PIMAGE_NT_HEADERS pNtHeaders = NULL; PIMAGE_IMPORT_DESCRIPTOR pImport = NULL; HMODULE hModule = 0; DWORD rvaImport = 0; DWORD rvaName = 0; DWORD rvaOriginalThunk = 0; DWORD rvaFirstThunk = 0; DWORD originalValue = 0; LPVOID pFirstValue = NULL; DWORD ordinalOfFunc = 0; CHAR* pFuncNameAddr = NULL; DWORD oldProtect = 0; pNtHeaders = GetNtHeaders(pImageBuffer); rvaImport = (*(pNtHeaders->OptionalHeader.DataDirectory + 1)).VirtualAddress; pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImageBuffer + rvaImport); //以OriginalFirstThunk为基准找到函数名/序号 //将新值补充到FirstThunk对应的ThunkValue中 while (rvaOriginalThunk = *((DWORD*)pImport)) { rvaFirstThunk = *((DWORD*)pImport + 4); rvaName = pImport->Name; if (!(hModule = ::LoadLibraryA((CHAR*)(DWORD)pImageBuffer + rvaName))) { //这一句不能加, printf 的dll可能没加载导致程序异常退出. //printf("加载dll失败 LastError: %d", GetLastError()); return FALSE; } //printf("DLL's name: %s\n", (char*)((DWORD)pImageBuffer + rvaName)); while (originalValue = *(DWORD*)((DWORD)pImageBuffer + (DWORD)rvaOriginalThunk)) { pFirstValue = (LPVOID)((DWORD)pImageBuffer + rvaFirstThunk); VirtualProtect(pFirstValue, 4, PAGE_READWRITE, &oldProtect); if ((originalValue & 0x80000000) == 0x80000000) { ordinalOfFunc = (originalValue & 0x7FFFFFFF); *(DWORD*)pFirstValue = (DWORD)GetProcAddress(hModule, MAKEINTRESOURCEA(ordinalOfFunc)); } else { pFuncNameAddr = (CHAR*)((DWORD)pImageBuffer + originalValue + 2); *(DWORD*)pFirstValue = (DWORD)GetProcAddress(hModule, pFuncNameAddr); } rvaOriginalThunk += 4; } pImport++; } return TRUE; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。