BOOL IATHookInjector::HookFunction(DWORD dwProcessId, CHAR* pModuleName, CHAR* pFunctionName, PVOID pHandler, DWORD dwHandlerSize) const { //PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE auto hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwProcessId); if (!hProcess) { printf("Error opening process\r\n"); return FALSE; } auto dwPEBAddress = FindRemotePEB(hProcess); if (!dwPEBAddress) { printf("Error finding remote PEB\r\n"); return FALSE; } auto pPEB = ReadRemotePEB(hProcess); if (!pPEB) { printf("Error reading remote PEB\r\n"); return FALSE; } auto pImage = ReadRemoteImage(hProcess, pPEB->ImageBaseAddress); if (!pImage) { printf("Error reading remote image\r\n"); return FALSE; } auto pImportDescriptors = ReadRemoteImportDescriptors(hProcess, pPEB->ImageBaseAddress, pImage->FileHeader->OptionalHeader.DataDirectory); if (!pImportDescriptors) { printf("Error reading remote import descriptors\r\n"); return FALSE; } for (DWORD i = 0; i < 0x2000; i++) { auto descriptor = pImportDescriptors[i]; auto pName = ReadRemoteDescriptorName(hProcess, pPEB->ImageBaseAddress, &descriptor); if (!pName) { printf("Error reading remote descriptor name\r\n"); return FALSE; } if (!_stricmp(pName, pModuleName)) { DWORD dwThunkArrayLen = BUFFER_SIZE / sizeof(IMAGE_THUNK_DATA32); auto pILT = ReadRemoteILT(hProcess, pPEB->ImageBaseAddress, &descriptor); if (!pILT) { printf("Error reading remote ILT\r\n"); return FALSE; } DWORD dwOffset = 0; for (dwOffset = 0; dwOffset < dwThunkArrayLen; dwOffset++) { auto pImportByName = ReadRemoteImportByName(hProcess, pPEB->ImageBaseAddress, &pILT[dwOffset]); if (!pImportByName) { printf("Error reading remote import by name\r\n"); return FALSE; } if (!strcmp(static_cast<char*>(pImportByName->Name), pFunctionName)) break; } auto pIAT = ReadRemoteIAT(hProcess, pPEB->ImageBaseAddress, &descriptor); if (!pIAT) { printf("Error reading remote IAT\r\n"); return FALSE; } auto dwOriginalAddress = pIAT[dwOffset].u1.AddressOfData; printf("Original import address: 0x%x\r\n", dwOriginalAddress); auto pImportImageBase = FindRemoteImageBase(hProcess, pPEB, pModuleName); if (!pImportImageBase) { printf("Could not find remote image base for %s\r\n", pModuleName); return FALSE; } auto pImportImage = ReadRemoteImage(hProcess, pImportImageBase); if (!pImportImage) { printf("Could not find remote image at 0x%p\r\n", pImportImageBase); return FALSE; } auto pImportTextHeader = FindSectionHeaderByName(pImportImage->Sections, pImportImage->NumberOfSections, ".text"); if (!pImportTextHeader) { printf("Could not find section header\r\n"); return FALSE; } auto pHandlerBuffer = new BYTE[dwHandlerSize]; memcpy(pHandlerBuffer, pHandler, dwHandlerSize); auto bSuccess = PatchDWORD(pHandlerBuffer, dwHandlerSize, 0xDEADBEEF, dwOriginalAddress); if (!bSuccess) { printf("Error patching import address into handler"); return FALSE; } auto dwHandlerAddress = DWORD(pImportImageBase) + pImportTextHeader->VirtualAddress + pImportTextHeader->SizeOfRawData - dwHandlerSize; // Write handler to text section bSuccess = WriteProcessMemory(hProcess, LPVOID(dwHandlerAddress), pHandlerBuffer, dwHandlerSize, nullptr); if (!bSuccess) { printf("Error writing process memory"); return FALSE; } printf("Handler address: 0x%x\r\n", dwHandlerAddress); auto pAddress = LPVOID(DWORD(pPEB->ImageBaseAddress) + descriptor.FirstThunk + (dwOffset * sizeof(IMAGE_THUNK_DATA32))); // Write IAT bSuccess = WriteProcessMemory(hProcess, pAddress, &dwHandlerAddress, 4, nullptr); if (!bSuccess) { printf("Error writing process memory"); return FALSE; } return TRUE; } if (!descriptor.Characteristics) { return FALSE; } } return FALSE; }
void Encoder::Encode(DWORD ID, DWORD Class, DWORD CTNumber, DWORD MType) { BOOL bInsertSurfaceNode = FALSE; BOOL bInsertTextureNode = FALSE; m_pCurrentNode = m_pRootNode; // COBRA - RED - Missing Last Texture Initialization to INVALID DWORD dwCurrentTexture=-1; DWORD dwCurrentzBias=0; NodeType LastType=ROOT; DXFlagsType LastFlags; LastFlags.w=0x00; bool ChangeSurface=false; while(m_pCurrentNode != NULL) { IdleMode(); NodeType Type=m_pCurrentNode->Type; DXFlagsType Flags; Flags.w=m_pCurrentNode->Flags.w; // Make all checks here ChangeSurface=false; if(Type!=LastType || Type==DOF || Type==CLOSEDOF || Type==SLOT ) ChangeSurface = true; if(Flags.b.Texture && m_pCurrentNode->Texture!=dwCurrentTexture) ChangeSurface = true; if(Flags.b.Texture != LastFlags.b.Texture) ChangeSurface=true; if(Flags.b.Alpha != LastFlags.b.Alpha) ChangeSurface=true; if(Flags.b.Gouraud != LastFlags.b.Gouraud ) ChangeSurface=true; if(Flags.b.Lite != LastFlags.b.Lite ) ChangeSurface=true; if((Flags.b.VColor) != (LastFlags.b.VColor)) ChangeSurface=true; if(Flags.b.zBias != LastFlags.b.zBias) ChangeSurface=true; if(Flags.b.zBias && m_pCurrentNode->dwzBias!=dwCurrentzBias) ChangeSurface=true; if(Flags.b.ChromaKey != LastFlags.b.ChromaKey) ChangeSurface=true; // if any change if(ChangeSurface){ // Patch the segments PatchDWORD(); switch (Type){ case DOT: case LINE: case TRIANGLE: // Check if a Textured new surace and last texture still valid if(Flags.b.Texture && m_pCurrentNode->Texture!=dwCurrentTexture){ // No moer used Texture node //WriteTextureNode(m_pCurrentNode); dwCurrentTexture=m_pCurrentNode->Texture; } dwCurrentzBias=m_pCurrentNode->dwzBias; // Write the new Surface WriteSurfaceNode(m_pCurrentNode, dwCurrentTexture); // New ID m_dwNodeID++; break; case DOF: // We've to insert a new DOF node {DXDof *pDof = (DXDof*)m_pCurrentNode; WriteDofNode(pDof);} // and reset surfaces properties Flags.w=0; dwCurrentTexture=-1; // New ID m_dwNodeID++; break; case SLOT: // We've to insert a new SLOT node WriteSlotNode((DXSlot*)m_pCurrentNode); // New ID m_dwNodeID++; break; case CLOSEDOF: // We've to insert a new END DOF node WriteDofEndNode(); // and reset surfaces properties Flags.w=0; dwCurrentTexture=-1; // New ID m_dwNodeID++; break; default : MessageBox(NULL, "Unknown SURFACE TYPE!!", "Encoder", 0); } ChangeSurface=false; LastFlags=Flags; LastType=Type; } switch(Type) { case DOT: { DXVertex *pVertex = (DXVertex*)m_pCurrentNode; D3DVERTEXEX dxVertex; InitializeVertex(&dxVertex); CopyVertex(&(pVertex->Vertex), pVertex->VColor, &dxVertex); /*memcpy((void*)&dxVertex, (const void*)&pVertex->Vertex, sizeof(pVertex->Vertex)); memcpy((void*)(&dxVertex + sizeof(pVertex->Vertex)), (const void*)&pVertex->VColor, sizeof(pVertex->VColor));*/ // Add vertex in NON INDEXED MODE Int16 iIndex = AddVertexToPool(&dxVertex, false); WriteBuffer((const void*)&iIndex, sizeof(iIndex)); } break; case LINE: { DXLine *pLine = (DXLine*)m_pCurrentNode; for(int i=0; i<2; i++) { D3DVERTEXEX dxVertex; InitializeVertex(&dxVertex); CopyVertex(&(pLine->Vertex[i]), pLine->VColor[i], &dxVertex); /*memcpy((void*)&dxVertex, (const void*)&pLine->Vertex[i], sizeof(pLine->Vertex[i])); memcpy((void*)(&dxVertex + sizeof(pLine->Vertex[i])), (const void*)&pLine->VColor[i], sizeof(pLine->VColor[0]));*/ Int16 iIndex = AddVertexToPool(&dxVertex); WriteBuffer((const void*)&iIndex, sizeof(iIndex)); } } break; case TRIANGLE: { DXTriangle *pTriangle = (DXTriangle*)m_pCurrentNode; for(int i=0; i<3; i++) { D3DVERTEXEX dxVertex; InitializeVertex(&dxVertex); CopyVertex(&(pTriangle->Vertex[i]), pTriangle->VColor[i], &dxVertex); /*BYTE *pVertex = (BYTE*)&dxVertex; memcpy((void*)&dxVertex, (const void*)&pTriangle->Vertex[i], sizeof(pTriangle->Vertex[i])); memcpy((void*)(pVertex + sizeof(pTriangle->Vertex[i])), (const void*)&pTriangle->VColor[i], sizeof(pTriangle->VColor[0]));*/ Int16 iIndex = AddVertexToPool(&dxVertex); WriteBuffer((const void*)&iIndex, sizeof(iIndex)); } } break; } // Update pointers //m_pPreviousNode = m_pCurrentNode; m_pCurrentNode = m_pCurrentNode->Next; //m_pNextNode = m_pCurrentNode != NULL ? m_pCurrentNode->Next : NULL; } //// Set last node total size (Node + Data (total indexes size)) //DWORD dwTotalNodeSize = (m_dwTotalSurfaceVertexes*sizeof(Int16) + sizeof(DxSurfaceType)); //memcpy((void*)m_pLastSurfaceNode, (const void*)&dwTotalNodeSize, sizeof(dwTotalNodeSize)); //// Add last node Vertex Counter to last surface node //memcpy(m_pLastSurfaceNode + 12, (const void*)&m_dwTotalSurfaceVertexes, sizeof(m_dwTotalSurfaceVertexes)); // Patch the segments PatchDWORD(); // Write ENDMODEL node DxEndModelType dxEndModelNode; dxEndModelNode.h.dwNodeSize = sizeof(DxEndModelType); dxEndModelNode.h.Type = DX_MODELEND; WriteBuffer((void*)&dxEndModelNode, sizeof(dxEndModelNode)); // Write total number of nodes ((DxDbHeader*)m_pHeader)->dwNodesNr=m_dwTotalNodeCount; // Write other header fields //DWORD dwVertexesPoolStart = (DWORD)(m_pBuffer + m_dwBufferOffset); ((DxDbHeader*)m_pHeader)->pVPool=m_dwBufferOffset; ((DxDbHeader*)m_pHeader)->dwPoolSize=m_dwVertexesPoolSize; ((DxDbHeader*)m_pHeader)->dwNVertices=m_dwVertexesNumber; // Copy vertexes pool after nodes section WriteBuffer((const void*)m_pVertexesPool, m_dwVertexesPoolSize); ((DxDbHeader*)m_pHeader)->Id=ID; ((DxDbHeader*)m_pHeader)->ModelSize= m_dwBufferOffset; ((DxDbHeader*)m_pHeader)->VBClass=Class; ((DxDbHeader*)m_pHeader)->Version=MODEL_VERSION|((MODEL_VERSION^0xffff)<<16); // Assign Materials Features m_dwBufferOffset=AssignSurfaceFeatures(m_pBuffer, CTNumber, MType); #ifdef CRYPTED_MODELS TheVbManager.Encrypt((DWORD*)m_pBuffer); #endif // Write file //WriteFile(); }
BOOL HookFunction(DWORD dwProcessId, CHAR* pModuleName, CHAR* pFunctionName, PVOID pHandler, DWORD dwHandlerSize) { HANDLE hProcess = OpenProcess ( PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, 0, dwProcessId ); if (!hProcess) { printf("Error opening process\r\n"); return FALSE; } DWORD dwPEBAddress = FindRemotePEB(hProcess); if (!dwPEBAddress) { printf("Error finding remote PEB\r\n"); return FALSE; } PEB* pPEB = ReadRemotePEB(hProcess); if (!pPEB) { printf("Error reading remote PEB\r\n"); return FALSE; } PLOADED_IMAGE pImage = ReadRemoteImage(hProcess, pPEB->ImageBaseAddress); if (!pImage) { printf("Error reading remote image\r\n"); return FALSE; } PIMAGE_IMPORT_DESCRIPTOR pImportDescriptors = ReadRemoteImportDescriptors ( hProcess, pPEB->ImageBaseAddress, pImage->FileHeader->OptionalHeader.DataDirectory ); if (!pImportDescriptors) { printf("Error reading remote import descriptors\r\n"); return FALSE; } for (DWORD i = 0; i < 0x2000; i++) { IMAGE_IMPORT_DESCRIPTOR descriptor = pImportDescriptors[i]; char* pName = ReadRemoteDescriptorName ( hProcess, pPEB->ImageBaseAddress, &descriptor ); if (!pName) { printf("Error reading remote descriptor name\r\n"); return FALSE; } BOOL bSuccess; if (!_stricmp(pName, pModuleName)) { DWORD dwThunkArrayLen = BUFFER_SIZE / sizeof(IMAGE_THUNK_DATA32); PIMAGE_THUNK_DATA32 pILT = ReadRemoteILT ( hProcess, pPEB->ImageBaseAddress, &descriptor ); if (!pILT) { printf("Error reading remote ILT\r\n"); return FALSE; } DWORD dwOffset = 0; for (dwOffset = 0; dwOffset < dwThunkArrayLen; dwOffset++) { PIMAGE_IMPORT_BY_NAME pImportByName = ReadRemoteImportByName ( hProcess, pPEB->ImageBaseAddress, &pILT[dwOffset] ); if (!pImportByName) { printf("Error reading remote import by name\r\n"); return FALSE; } if (!strcmp((char*)pImportByName->Name, pFunctionName)) break; } PIMAGE_THUNK_DATA32 pIAT = ReadRemoteIAT ( hProcess, pPEB->ImageBaseAddress, &descriptor ); if (!pIAT) { printf("Error reading remote IAT\r\n"); return FALSE; } DWORD dwOriginalAddress = pIAT[dwOffset].u1.AddressOfData; printf("Original import address: 0x%p\r\n", dwOriginalAddress); PVOID pImportImageBase = FindRemoteImageBase ( hProcess, pPEB, pModuleName ); if (!pImportImageBase) { printf("Could not find remote image base for %s\r\n", pModuleName); return FALSE; } PLOADED_IMAGE pImportImage = ReadRemoteImage ( hProcess, pImportImageBase ); if (!pImportImage) { printf("Could not find remote image at 0x%p\r\n", pImportImageBase); return FALSE; } PIMAGE_SECTION_HEADER pImportTextHeader = FindSectionHeaderByName ( pImportImage->Sections, pImportImage->NumberOfSections, ".text" ); if (!pImportTextHeader) { printf("Could not find section header\r\n"); return FALSE; } BYTE* pHandlerBuffer = new BYTE[dwHandlerSize]; memcpy(pHandlerBuffer, pHandler, dwHandlerSize); BOOL bSuccess = PatchDWORD ( pHandlerBuffer, dwHandlerSize, 0xDEADBEEF, dwOriginalAddress ); if (!bSuccess) { printf("Error patching import address into handler"); return FALSE; } DWORD dwHandlerAddress = (DWORD)pImportImageBase + pImportTextHeader->VirtualAddress + pImportTextHeader->SizeOfRawData - dwHandlerSize; // Write handler to text section bSuccess = WriteProcessMemory ( hProcess, (LPVOID)dwHandlerAddress, pHandlerBuffer, dwHandlerSize, 0 ); if (!bSuccess) { printf("Error writing process memory"); return FALSE; } printf("Handler address: 0x%p\r\n", dwHandlerAddress); LPVOID pAddress = (LPVOID)((DWORD)pPEB->ImageBaseAddress + descriptor.FirstThunk + (dwOffset * sizeof(IMAGE_THUNK_DATA32))); // Write IAT bSuccess = WriteProcessMemory ( hProcess, pAddress, &dwHandlerAddress, 4, 0 ); if (!bSuccess) { printf("Error writing process memory"); return FALSE; } return TRUE; } else if (!descriptor.Characteristics) return FALSE; } return FALSE; }