15,471
社区成员
发帖
与我相关
我的任务
分享
// create a remote thread, and start LoadLibrary to load dll that we make, in the dll, we can
// hook apis and can do everything we want
BOOL CreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pfnStartAddr, LPVOID pRemoteMem)
{
BOOL bRet = FALSE;
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, pRemoteMem, 0, NULL);
do
{
if(!hThread)
{
PrintError(_T("CreateRemoteThread"), GetLastError(), __MYFILE__, __LINE__);
break;
}
TCOUT << _T("Waiting for the end of the remote thread...") << endl;
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
hThread = NULL;
bRet = TRUE;
} while (FALSE);
return bRet;
}
// write infomation to file-mapping, the infomation includes witch apis need to be (un)hooked,
// and includes the (un)hook results and so on
LPVOID WriteFileMapping(HANDLE hMap, CONTENT_FILE_MAPPING content)
{
LPVOID pContent = NULL;
do
{
if(!hMap)
{
PrintMsg(_T("WriteFileMapping fail : hMap is null, file : %s, line : %d\n"),
__FILE__, __LINE__);
break;
}
pContent = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(content));
if(!pContent)
{
PrintError(_T("MapViewOfFile"), GetLastError(), __MYFILE__, __LINE__);
break;
}
memcpy(pContent, &content, sizeof(content));
} while (FALSE);
return pContent;
}
// if no apis be hooked, we must free the library
BOOL UnLoadModule(DWORD dwProcesssId, LPCTSTR lpModuleName)
{
BOOL bRet = FALSE;
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
HANDLE hProcess = NULL;
HMODULE hModule = NULL;
me32.dwSize = sizeof(me32);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcesssId);
do
{
if(!hProcess)
{
PrintError(_T("OpenProcess"), GetLastError(), __MYFILE__, __LINE__);
break;
}
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcesssId);
if(INVALID_HANDLE_VALUE == hModuleSnap)
{
PrintError(_T("CreateToolhelp32Snapshot"), GetLastError(), __MYFILE__, __LINE__);
break;
}
if(!Module32First(hModuleSnap, &me32))
{
PrintError(_T("Module32First"), GetLastError(), __MYFILE__, __LINE__);
break;
}
int nRefCount = 0;
do
{
if(!StrCmpI(me32.szModule, lpModuleName) || !StrCmpI(me32.szExePath, lpModuleName))
{
hModule = me32.hModule;
nRefCount = me32.ProccntUsage;
break;
}
} while(Module32Next(hModuleSnap, &me32));
LPTHREAD_START_ROUTINE pfnStartAddr =
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "FreeLibrary");
if (!pfnStartAddr)
{
PrintError(_T("GetProcAddress"), GetLastError(), __MYFILE__, __LINE__);
break;
}
for (int i = 0; i < nRefCount; i++)
{
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, hModule, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CLOSE_HANDLE(hThread);
}
PrintMsg(_T("FreeLibrary %s in the process %d finished!\n"), lpModuleName, dwProcesssId);
bRet = TRUE;
} while (FALSE);
CLOSE_HANDLE(hModuleSnap);
CLOSE_HANDLE(hProcess);
return bRet;
}
// hook the specify api
// pRecallApiInfo : infomation of the api
BOOL HookSpecifyApi(PRECALL_API_INFO pRecallApiInfo)
{
BOOL bRet = FALSE;
do
{
if (!pRecallApiInfo)
{
break;
}
if (pRecallApiInfo->pOrgfnMem)
{
bRet = TRUE;
break;
}
HMODULE hModule = LoadLibrary(pRecallApiInfo->lpDllName);
if (!hModule)
{
PrintError(_T("LoadLibrary"), GetLastError(), __MYFILE__, __LINE__);
break;
}
USES_CONVERSION;
FARPROC pfnStartAddr = (FARPROC)GetProcAddress(hModule, T2CA(pRecallApiInfo->lpFunctionName));
pRecallApiInfo->lpApiAddr = pfnStartAddr;
if (!pfnStartAddr)
{
PrintError(_T("GetProcAddress"), GetLastError(), __MYFILE__, __LINE__);
break ;
}
// we must save the first few bytes of the api(at least five, and these few bytes must complete
// the assembly codes), then make the 5 bytes in front of api to jump to our function, and our
// function must execute the few bytes saved before, and then jump to the api to execute
// the rest code in the api
int nSize = 0;
int nDisassemblerLen = 0;
while(nSize < 5)
{
// GetOpCodeSize can get the assembly code size
nDisassemblerLen = GetOpCodeSize((BYTE*)(pfnStartAddr) + nSize);
nSize = nDisassemblerLen + nSize;
}
DWORD dwProtect = 0;
if (!VirtualProtect(pfnStartAddr, nSize, PAGE_EXECUTE_READWRITE, &dwProtect))
{
PrintError(_T("VirtualProtect"), GetLastError(), __MYFILE__, __LINE__);
break ;
}
// be sure that we must change pOrgfnMem's protect, because the code in pOrgfnMem
// also need to execute
pRecallApiInfo->pOrgfnMem = new BYTE[5 + nSize];
DWORD dwMemProtect = 0;
if (!VirtualProtect(pRecallApiInfo->pOrgfnMem, 5 + nSize, PAGE_EXECUTE_READWRITE, &dwMemProtect))
{
delete [] pRecallApiInfo->pOrgfnMem;
pRecallApiInfo->pOrgfnMem = NULL;
PrintError(_T("VirtualProtect"), GetLastError(), __MYFILE__, __LINE__);
break ;
}
pRecallApiInfo->nOrgfnMemSize = 5 + nSize;
memcpy(pRecallApiInfo->pOrgfnMem, pfnStartAddr, nSize);
*(BYTE*)(pRecallApiInfo->pOrgfnMem + nSize) = 0xE9;
*(DWORD*)(pRecallApiInfo->pOrgfnMem + nSize + 1)
= (DWORD)pfnStartAddr + nSize - (DWORD)(pRecallApiInfo->pOrgfnMem + 5 + nSize);
*(BYTE*)(pfnStartAddr) = 0xE9;
*(DWORD*)((BYTE*)pfnStartAddr + 1) = (DWORD)pRecallApiInfo->lpRecallfn - ((DWORD)pfnStartAddr + 5);
memset((BYTE*)pfnStartAddr + 5, 0x90, nSize - 5);
// be sure that we must set the rest to 0x90(assembly code for nop, do nothing,
// and occupy one byte), because we should't change the assembly code
VirtualProtect(pfnStartAddr, nSize, dwProtect, &dwProtect);
bRet = TRUE;
} while (FALSE);
return bRet;
}
int WINAPI MyMessageBoxA(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
int nOrderHookApi = ORDER_MESSAGEBOXA;
int nRet = 0;
static int i = 1;
if (g_arHookAPIs[nOrderHookApi].pOrgfnMem)
{
USES_CONVERSION;
PrintMsgA("%-18s %08d : 0x%08x \"%s\" \"%s\" 0x%08x\n",
T2CA(g_arHookAPIs[nOrderHookApi].lpFunctionName),
i++, hWnd, VALID_CHAR(lpText), VALID_CHAR(lpCaption), uType);
nRet = ((pfnMessageBoxA)(LPVOID)g_arHookAPIs[nOrderHookApi].pOrgfnMem)(
hWnd, "HelloWorld", "Caption", MB_OKCANCEL);
}
return nRet;
}