Проблема Вопрос про поводу IAT-хука FASM

Gemfory

Green Team
03.01.2026
14
5
C:
format PE64 GUI 4.0 DLL
entry DllEntryPoint

include 'C:\FLAT\INCLUDE\win64ax.inc'

section '.data' data writeable
    Message db "hack",0
    caption db "hook",0
    user32_dll db "user32.dll",0
    function db "MessageBoxA",0

    dosHeader dq 0
    ntHeaders dq 0

section '.text' code executable

proc DllEntryPoint hinstDLL, reason, reserved
    cmp edx, 1
    jne .skip
    call installIAT
.skip:
    mov eax, 1
    ret
endp
// тут хук ставлю без возврата оригинала, для проверки
proc HookMessageBoxA hWnd, lpText, lpCaption, uType
    sub rsp, 28h

    xor rcx, rcx
    lea rdx, [Message]
    lea r8, [caption]
    xor r9, r9
    call[MessageBoxA]
    add rsp, 28h
endp


// парсинг IAT
installIAT:
    sub rsp, 28h

    xor rcx, rcx
    call[GetModuleHandle]
    mov [dosHeader], rax
    mov edi, dword [rax+3Ch]
    add rax, rdi
    mov [ntHeaders], rax

    mov eax, dword [rax+90h]
    add rax, [dosHeader]
    mov rsi, rax
.dll_loop:
    mov eax, dword [rsi+12h]
    test eax, eax
    jz .error
    mov rdi, [dosHeader]
    add rdi, rax

    mov rbx, [dosHeader]
    add ebx, dword [rsi+10h]

.loop_IAT:
    invoke GetProcAddress, <invoke GetModuleHandle, user32_dll>, function
    cmp [rbx], rax
    je .patch
    add rbx, 8
    jmp .loop_IAT
.patch:
    lea r9, [ntHeaders]
    mov rcx, rbx
    mov rdx, 8
    mov r8, 40h
    call[VirtualProtect]

    lea rax, [HookMessageBoxA]
    mov [rbx], rax
    jmp .error
.error:
    add rsp, 28h
    ret
    
section '.idata' import data readable

library kernel32, 'KERNEL32.DLL', \
        user32,   'USER32.DLL'
import kernel32, \
       GetModuleHandle, 'GetModuleHandleA', \
       GetProcAddress,  'GetProcAddress', \
       VirtualProtect,  'VirtualProtect'

import user32, \
       MessageBoxA, 'MessageBoxA'

section '.reloc' fixups data readable discardable


Всем привет.
Вопрос, почему не хукается?
IAT спарсил я вроде правильно.

Заранее благодарен если кто поможет решить.
 
Вопрос, почему не хукается?
1. Нужна секция экспорта в DLL, иначе она не загрузится в процесс родителя.

2. Если до ".loop_IAT" всё нормально, то сохраняйте регистр RBX на входе, т.к. GetProcAddress() и VirtualProtect() могут его испортить.

3. Посмотрите, что происходит в отладчике x64dbg. Предварительно зайдите в его параметры, и установите чекбокс на "UserDllEntry".

4. На вкладке "Карта памяти" отладчика можно узнать, по какому адресу загрузилась ваша либа, и правой клавишей перейти в её дизасм.листинг, чтобы поставить куда-нибудь бряк.
 
  • Нравится
Реакции: Gemfory
1. Нужна секция экспорта в DLL, иначе она не загрузится в процесс родителя.

2. Если до ".loop_IAT" всё нормально, то сохраняйте регистр RBX на входе, т.к. GetProcAddress() и VirtualProtect() могут его испортить.

3. Посмотрите, что происходит в отладчике x64dbg. Предварительно зайдите в его параметры, и установите чекбокс на "UserDllEntry".

4. На вкладке "Карта памяти" отладчика можно узнать, по какому адресу загрузилась ваша либа, и правой клавишей перейти в её дизасм.листинг, чтобы поставить куда-нибудь бряк.
Спасибо вам огромное, пофиксил.
 
  • Нравится
Реакции: Marylin
В хвосте процедуры "HookMessageBoxA" после add rsp,28h поставьте ret.
Да и call [MessageBoxA] в ней отфутболивает непонятно куда.
В общем нужно в отладчике смотреть..
 
Короче вот такой вариант работает..
Свою dll загружайте в процесс динамически LoadLibrary(),
а проблема была внутри proc HookMessageBoxA:

C-подобный:
format PE64 GUI 4.0 DLL
entry DllEntryPoint
include 'win64ax.inc'

section '.data' data writeable
    Message    db "hack",0
    Caption    db "hook",0
    user32_dll db "user32.dll",0
    function   db "MessageBoxA",0

    dosHeader  dq 0
    ntHeaders  dq 0

section '.text' code executable

proc DllEntryPoint hinstDLL, reason, reserved
    cmp edx, 1
    jne .skip
    call installIAT
.skip:
    mov eax, 1
    ret
endp

;//--------------
proc HookMessageBoxA hWnd, lpText, lpCaption, uType
     mov    rax,[rsp]
     push   rbp rax
     invoke MessageBoxA,0,Message,Caption,0
     ret
endp
;//--------------
installIAT:
    sub rsp, 28h

    xor rcx, rcx
    call [GetModuleHandle]
    mov [dosHeader], rax
    mov edi, dword [rax+3Ch]
    add rax, rdi
    mov [ntHeaders], rax

    mov eax, dword [rax+90h]
    add rax, [dosHeader]
    mov rsi, rax
.dll_loop:
    mov eax, dword [rsi+12h]
    test eax, eax
    jz .error
    mov rdi, [dosHeader]
    add rdi, rax

    mov rbx, [dosHeader]
    add ebx, dword [rsi+10h]

.loop_IAT:
    invoke GetProcAddress, <invoke GetModuleHandle, user32_dll>, function
    cmp [rbx], rax
    je .patch
    add rbx, 8
    jmp .loop_IAT
.patch:
    lea r9, [ntHeaders]
    mov rcx, rbx
    mov rdx, 8
    mov r8, 40h
    call [VirtualProtect]

    lea rax, [HookMessageBoxA]
    mov [rbx], rax
.error:
    add rsp, 28h
    ret
;//------------------------------------
section '.idata' import data readable

library kernel32, 'KERNEL32.DLL', \
        user32,   'USER32.DLL'
import  kernel32, \
        GetModuleHandle, 'GetModuleHandleA', \
        GetProcAddress,  'GetProcAddress', \
        VirtualProtect,  'VirtualProtect'

import user32, \
       MessageBoxA, 'MessageBoxA'

section '.reloc' fixups data readable discardable
 
  • Нравится
Реакции: Gemfory
Короче вот такой вариант работает..
Свою dll загружайте в процесс динамически LoadLibrary(),
а проблема была внутри proc HookMessageBoxA:

C-подобный:
format PE64 GUI 4.0 DLL
entry DllEntryPoint
include 'win64ax.inc'

section '.data' data writeable
    Message    db "hack",0
    Caption    db "hook",0
    user32_dll db "user32.dll",0
    function   db "MessageBoxA",0

    dosHeader  dq 0
    ntHeaders  dq 0

section '.text' code executable

proc DllEntryPoint hinstDLL, reason, reserved
    cmp edx, 1
    jne .skip
    call installIAT
.skip:
    mov eax, 1
    ret
endp

;//--------------
proc HookMessageBoxA hWnd, lpText, lpCaption, uType
     mov    rax,[rsp]
     push   rbp rax
     invoke MessageBoxA,0,Message,Caption,0
     ret
endp
;//--------------
installIAT:
    sub rsp, 28h

    xor rcx, rcx
    call [GetModuleHandle]
    mov [dosHeader], rax
    mov edi, dword [rax+3Ch]
    add rax, rdi
    mov [ntHeaders], rax

    mov eax, dword [rax+90h]
    add rax, [dosHeader]
    mov rsi, rax
.dll_loop:
    mov eax, dword [rsi+12h]
    test eax, eax
    jz .error
    mov rdi, [dosHeader]
    add rdi, rax

    mov rbx, [dosHeader]
    add ebx, dword [rsi+10h]

.loop_IAT:
    invoke GetProcAddress, <invoke GetModuleHandle, user32_dll>, function
    cmp [rbx], rax
    je .patch
    add rbx, 8
    jmp .loop_IAT
.patch:
    lea r9, [ntHeaders]
    mov rcx, rbx
    mov rdx, 8
    mov r8, 40h
    call [VirtualProtect]

    lea rax, [HookMessageBoxA]
    mov [rbx], rax
.error:
    add rsp, 28h
    ret
;//------------------------------------
section '.idata' import data readable

library kernel32, 'KERNEL32.DLL', \
        user32,   'USER32.DLL'
import  kernel32, \
        GetModuleHandle, 'GetModuleHandleA', \
        GetProcAddress,  'GetProcAddress', \
        VirtualProtect,  'VirtualProtect'

import user32, \
       MessageBoxA, 'MessageBoxA'

section '.reloc' fixups data readable discardable
Боже, спасибо огромное, помогло.
Дня два искал фикс, ставить хуки на ассемблере это конечно тот еще кошмар, особенно муторство с ABI...
 
  • Нравится
Реакции: Marylin
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab