@sddvxd

Как перевести этот код с C++?

Добрый день!

Есть функция для смены адреса функции в разделе импорта PE файла:

Процедура из класса
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()");
}


Пытаюсь переписать его на NASM. Первая итерация проходит успешно: я в отладчике могу увидеть имя dll файла. Со второй итерации происходит урезание/коверканье имен (что-то идет не так)

Процедура на 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 _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


Несколько дней голову ломаю - в чем может быть проблема. Вот структуры IMAGE_IMPORT_DESCRIPTOR и IMAGE_THUNK_DATA

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;


Функция на NASM не дописана, из-за этой ошибки с неправильным проходом по памяти
Буду очень благодарен за любую помощь!
  • Вопрос задан
  • 345 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Как перевести этот код с C++?

И, главное, зачем? И чем для этой цели не подошёл компилятор С++?

mov ebx, [ebp - 8]

Нифига не mov, должно быть lea ebx, [ebp - 8]

lea edx, [ebx + ecx + 4] ; add FirstThunk RVA to base. Offset &function is 4

Нифига +4 не нужно. Смещение &function == 0.

lea edx, [edx + 20] ;size of IMAGE_THUNK_DATA

Нифига не +20, размер этой структуры -- 4.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы