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()");
}
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 _GetModuleHandleA@4
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 _ImageDirectoryEntryToData@16
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
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;
Как перевести этот код с C++?
mov ebx, [ebp - 8]
lea ebx, [ebp - 8]
lea edx, [ebx + ecx + 4] ; add FirstThunk RVA to base. Offset &function is 4
lea edx, [edx + 20] ;size of IMAGE_THUNK_DATA