S
S
sddvxd2019-05-31 22:24:29
C++ / C#
sddvxd, 2019-05-31 22:24:29

How to translate this code from C++?

Good afternoon!
There is a function to change the address of a function in the import section of a PE file:

class procedure
PROC replaceProcAddress(LPCSTR callerModule, PROC original, PROC swap){
    HMODULE callerHandle = GetModuleHandleA(callerModule);
    if(callerHandle == nullptr)
        throw Exception(L"callerHandle is NULL in Process::replaceProcAddress");

    ULONG size;
    bool found = false;
    PIMAGE_IMPORT_DESCRIPTOR pImageDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(ImageDirectoryEntryToData(callerHandle, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
    if(pImageDesc == nullptr)
        throw Exception(L"PIMAGE_IMPORT_DESCRIPTOR is NULL in Process::replaceProcAddress()");

    for(; pImageDesc->Name; pImageDesc++){
        PSTR pModName = reinterpret_cast<PSTR>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->Name);
            PIMAGE_THUNK_DATA pThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->FirstThunk);
            for(; pThunkData->u1.Function; pThunkData++){
                PROC* ppOriginalFunc = reinterpret_cast<PROC*>(&pThunkData->u1.Function);
                if(*ppOriginalFunc == original){
                    found = true;
                    DWORD dwOldProtect;
                    if(VirtualProtect(ppOriginalFunc, sizeof(swap), PAGE_WRITECOPY, &dwOldProtect)){
                        if(!WriteProcessMemory(getHandle(), ppOriginalFunc, &swap, sizeof(swap), NULL))
                            throw Exception(L"Write memory is failed for replaceProcAddress");
                        VirtualProtect(ppOriginalFunc, sizeof(swap), dwOldProtect, &dwOldProtect);
                    }
                }
            }
    }
    if(found) return swap;
    throw Exception(L"Address of procedure is not found in Process::replaceProcAddress()");
}

I'm trying to rewrite it to NASM. The first iteration is successful: I can see the name of the dll file in the debugger. From the second iteration there is a reduction / mangling of names (something goes wrong)
Procedure on NASM
replace_function: ; stdcall
  push ebp
  mov ebp, esp
  
  sub esp, 16 ; base handle - 4, size of IMAGE_IMPORT_DESCRIPTOR - 8,
        ; PIMAGE_IMPORT_DESCRIPTOR - 12, PIMAGE_THUNK_DATA - 16
  
  push 0
  call [email protected]
  test eax, eax
  jz .end
  
  mov [ebp - 4], eax
  mov ebx, [ebp - 8]
  
  push ebx
  push IMAGE_DIRECTORY_ENTRY_IMPORT
  push TRUE
  push eax
  call [email protected]
  test eax, eax
  jz .end_not_found
  mov [ebp - 12], eax ; PIMAGE_IMPORT_DESCRIPTOR
  
  mov ebx, [ebp - 4]
  
.next_struct:
  mov ecx, [eax + 12] ; PIMAGE_IMPORT_DESCRIPTOR + 12 (Name of module pointer) and get RVA
  test ecx, ecx
  jz .end_not_found
  lea ecx, [ecx + ebx]

  mov ecx, [eax + 16] ; PIMAGE_IMPORT_DESCRIPTOR + 16 (Pointer to FirstThunk structure) and get RVA
  lea edx, [ebx + ecx + 4] ; add FirstThunk RVA to base. Offset &function is 4
.loop1:
  mov esi, [edx] ; FirstThunk->Function
  cmp esi, [ebp + 8]
  je .found
  lea edx, [edx + 20] ;size of IMAGE_THUNK_DATA
  test esi, esi
  jne .loop1
  lea ebx, [ebx + 20] ;size of IMAGE_IMPORT_DESCRIPTOR
  jmp .next_struct
  
.end:
  mov esp, ebp
  pop ebp
  ret
  
.end_not_found:
  mov eax, 0 ; not found value
  jmp .end
  
.found:
  mov eax, ecx
  jmp .end

I've been scratching my head for a few days to figure out what could be the problem. Here are the IMAGE_IMPORT_DESCRIPTOR and IMAGE_THUNK_DATA structures
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
  union {
       DWORD Characteristics; // 0 for terminating null import descriptor
       DWORD OriginalFirstThunk; // RVA to original unbound IAT
   };
   DWORD TimeDateStamp; // 0 if not bound,
   // -1 if bound, and real date\time stamp
   // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new)
   // O.W. date/time stamp of DLL bound to (old)
   DWORD ForwarderChain; // -1 if no forwarders
   DWORD Name;
   DWORD FirstThunk; // RVA to IAT
  } IMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_THUNK_DATA32 {
  union {
     DWORD ForwarderString;
     DWORD Function;
     DWORD Ordinal;
     DWORD AddressOfData;
   } u1;
 } IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;

The function on NASM is not completed, due to this error with an incorrect memory pass
I would be very grateful for any help!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2019-05-31
@sddvxd

How to translate this code from C++?

And, most importantly, why? And why did the C ++ compiler not fit for this purpose?
Nothing mov, must belea ebx, [ebp - 8]
Nifiga +4 is not needed. Offset &function == 0.
It's not +20, the size of this structure is 4.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question