Код (Text): bool SpliceBridgeAllProlog(__in DWORD addr,__in DWORD new_addr,__out DWORD& true_addr,int prolog_size) { DWORD Protects= NULL; DWORD JA= NULL; BYTE* bridg= NULL; if(addr && new_addr) { bridg=(BYTE*)VirtualAlloc(NULL,5+prolog_size,MEM_COMMIT,PAGE_EXECUTE_READWRITE); VirtualProtect((LPVOID)addr, prolog_size, PAGE_EXECUTE_READWRITE, &Protects); ReadProcessMemory(GetCurrentProcess(), (LPVOID)addr, bridg, prolog_size, 0); bridg[prolog_size]=0xE9; JA=addr-(DWORD)bridg-prolog_size; memcpy(&bridg[prolog_size+1],&JA,4); true_addr=(DWORD)bridg; BYTE* jmp= new BYTE(prolog_size); jmp[0]=0xE9; JA=(DWORD)new_addr - addr - prolog_size; memcpy(&jmp[1],&JA,4); for (int i=5;i<=prolog_size;i++) jmp[i]=0x90; if(WriteProcessMemory(GetCurrentProcess(),(LPVOID)addr,jmp, prolog_size, 0)) { VirtualProtect((LPVOID)addr, prolog_size, Protects, &Protects); return true; } } return false; } Подскажите что не так, нужно перехватить функцию Код (Text): .text:00552E40 .text:00552E40 ; =============== S U B R O U T I N E ======================================= .text:00552E40 .text:00552E40 .text:00552E40 ; int __cdecl strOut(HDC, LPCSTR, LPCSTR) .text:00552E40 strOut proc near .text:00552E40 .text:00552E40 .text:00552E40 var_4 = dword ptr -4 .text:00552E40 arg_0 = dword ptr 4 .text:00552E40 arg_4 = dword ptr 8 .text:00552E40 arg_8 = dword ptr 0Ch .text:00552E40 .text:00552E40 push ecx .text:00552E41 push ebx .text:00552E42 push ebp .text:00552E43 push esi .text:00552E44 mov esi, [esp+10h+arg_0] .text:00552E48 mov eax, [esi] .text:00552E4A mov edx, [eax+44h] .text:00552E4D push edi .text:00552E4E lea ecx, [esp+14h+arg_0] ; Load Effective Address .text:00552E52 push ecx .text:00552E53 push esi .text:00552E54 call edx ; Indirect Call Near Procedure .text:00552E56 push offset aArial ; "Arial" .text:00552E5B push 0 ; DWORD .text:00552E5D push 4 ; DWORD .text:00552E5F push 0 ; DWORD .text:00552E61 push 0 ; DWORD .text:00552E63 push 0CCh ; DWORD .text:00552E68 push 0 ; DWORD .text:00552E6A push 0 ; DWORD .text:00552E6C push 0 ; DWORD .text:00552E6E push 2BCh ; int .text:00552E73 push 0 ; int .text:00552E75 push 0 ; int .text:00552E77 push 0 ; int .text:00552E79 push 12h ; int .text:00552E7B call ds:CreateFontA ; Indirect Call Near Procedure .text:00552E81 mov ebx, eax .text:00552E83 mov eax, [esp+14h+arg_0] .text:00552E87 push ebx ; HGDIOBJ .text:00552E88 push eax ; HDC .text:00552E89 call ds:SelectObject ; Indirect Call Near Procedure .text:00552E8F mov ecx, [esp+14h+arg_0] .text:00552E93 push 6 ; UINT .text:00552E95 push ecx ; HDC .text:00552E96 mov [esp+1Ch+var_4], eax .text:00552E9A call ds:SetTextAlign ; Indirect Call Near Procedure .text:00552EA0 mov edx, [esp+14h+arg_0] .text:00552EA4 push 1 ; int .text:00552EA6 push edx ; HDC .text:00552EA7 call ds:SetBkMode ; Indirect Call Near Procedure .text:00552EAD mov eax, [esp+14h+arg_0] .text:00552EB1 push 0FFFFh ; COLORREF .text:00552EB6 push eax ; HDC .text:00552EB7 call ds:SetTextColor ; Indirect Call Near Procedure .text:00552EBD mov edi, [esp+14h+arg_4] .text:00552EC1 mov eax, edi .text:00552EC3 lea ebp, [eax+1] ; Load Effective Address .text:00552EC6 .text:00552EC6 loc_552EC6: ; CODE XREF: strOut+8Dj .text:00552EC6 mov cl, [eax] .text:00552EC8 add eax, 1 ; Add .text:00552ECB test cl, cl ; Logical Compare .text:00552ECD jnz short loc_552EC6 ; Jump if Not Zero (ZF=0) .text:00552ECF mov ecx, [esp+14h+arg_0] .text:00552ED3 sub eax, ebp ; Integer Subtraction .text:00552ED5 push eax ; int .text:00552ED6 push edi ; LPCSTR .text:00552ED7 mov edi, ds:TextOutA .text:00552EDD push 196h ; int .text:00552EE2 push 0C1h ; int .text:00552EE7 push ecx ; HDC .text:00552EE8 call edi ; TextOutA ; Indirect Call Near Procedure .text:00552EEA mov ecx, [esp+14h+arg_8] .text:00552EEE mov eax, ecx .text:00552EF0 lea ebp, [eax+1] ; Load Effective Address .text:00552EF3 .text:00552EF3 loc_552EF3: ; CODE XREF: strOut+BAj .text:00552EF3 mov dl, [eax] .text:00552EF5 add eax, 1 ; Add .text:00552EF8 test dl, dl ; Logical Compare .text:00552EFA jnz short loc_552EF3 ; Jump if Not Zero (ZF=0) .text:00552EFC mov edx, [esp+14h+arg_0] .text:00552F00 sub eax, ebp ; Integer Subtraction .text:00552F02 push eax ; int .text:00552F03 push ecx ; LPCSTR .text:00552F04 push 1A9h ; int .text:00552F09 push 0C1h ; int .text:00552F0E push edx ; HDC .text:00552F0F call edi ; TextOutA ; Indirect Call Near Procedure .text:00552F11 mov eax, [esp+14h+var_4] .text:00552F15 mov ecx, [esp+14h+arg_0] .text:00552F19 push eax ; HGDIOBJ .text:00552F1A push ecx ; HDC .text:00552F1B call ds:SelectObject ; Indirect Call Near Procedure .text:00552F21 push ebx ; HGDIOBJ .text:00552F22 call ds:DeleteObject ; Indirect Call Near Procedure .text:00552F28 mov eax, [esp+14h+arg_0] .text:00552F2C mov edx, [esi] .text:00552F2E mov ecx, [edx+68h] .text:00552F31 push eax .text:00552F32 push esi .text:00552F33 call ecx ; Indirect Call Near Procedure .text:00552F35 pop edi .text:00552F36 pop esi .text:00552F37 pop ebp .text:00552F38 pop ebx .text:00552F39 pop ecx .text:00552F3A retn ; Return Near from Procedure .text:00552F3A strOut endp пеередаю 5 отрабатывает обработчик и падает, передаю 8 падает сразу при запуске.
ReadProcessMemory(GetCurrentProcess(..... - уже не надоело из своего АП так память читать? Сдампь процесс сразу после сплайса и посмотри что там насплайсилось... или под отладчиком потрейси, поставив бряк на начало функции, которую сплайсишь. -вообще жесть
Код (Text): .text:00552E40 push ecx .text:00552E41 push ebx .text:00552E42 push ebp .text:00552E43 push esi .text:00552E44 mov esi, [esp+10h+arg_0] Перезаписывать нада это я так понимаю, вписываем джамп и дополняем нопами тремя. В мост копируем это и джамп на функцию + 8? да?
Код (Text): bool SpliceBridgeAllProlog(__in DWORD addr,__in DWORD new_addr,__out DWORD& true_addr,int prolog_size) { DWORD Protects= NULL; DWORD JA= NULL; BYTE* bridg= NULL; if(addr && new_addr) { bridg=(BYTE*)VirtualAlloc(NULL,5+prolog_size,MEM_COMMIT,PAGE_EXECUTE_READWRITE); VirtualProtect((LPVOID)addr, prolog_size, PAGE_EXECUTE_READWRITE, &Protects); memcpy(bridg,(LPVOID)addr, prolog_size); bridg[prolog_size]=0xE9; JA=addr-(DWORD)bridg-prolog_size; memcpy(&bridg[prolog_size+1],&JA,4); true_addr=(DWORD)bridg; BYTE* jmp= new BYTE(prolog_size); jmp[0]=0xE9; JA=(DWORD)new_addr - addr - prolog_size; memcpy(&jmp[1],&JA,4); memset(&jmp[5],0x90,prolog_size-5); if(memcpy(jmp,(LPVOID)addr, prolog_size, )) { VirtualProtect((LPVOID)addr, prolog_size, Protects, &Protects); return true; } } return false; } Пусть будет такой вариант, помогите с ним пожалуйсто.
Код (Text): bool SpliceBridgeAllProlog(__in DWORD addr,__in DWORD new_addr,__out DWORD& true_addr,int prolog_size) { DWORD Protects= NULL; DWORD JA= NULL; BYTE* bridg= NULL; if(addr && new_addr) { bridg=(BYTE*)VirtualAlloc(NULL,5+prolog_size,MEM_COMMIT,PAGE_EXECUTE_READWRITE); VirtualProtect((LPVOID)addr, prolog_size, PAGE_EXECUTE_READWRITE, &Protects); memcpy(bridg,(LPVOID)addr, prolog_size); bridg[prolog_size]=0xE9; JA=addr-(DWORD)bridg-prolog_size; memcpy(&bridg[prolog_size+1],&JA,4); true_addr=(DWORD)bridg; BYTE* jmp= new BYTE(prolog_size); jmp[0]=0xE9; JA=(DWORD)new_addr - addr - prolog_size; memcpy(&jmp[1],&JA,4); memset(&jmp[5],0x90,prolog_size-5); if(memcpy((LPVOID)addr,jmp, prolog_size, )) { VirtualProtect((LPVOID)addr, prolog_size, Protects, &Protects); return true; } } return false; } точнее так
Код (Text): int __cdecl MystrOut(HDC hDC, LPCSTR a2, LPCSTR a3); int (__cdecl *pstrOut)(HDC hDC, LPCSTR a2, LPCSTR a3); volatile ULONG* pGameTextOut=(ULONG*)0x00552E40; Код (Text): ret=SpliceBridgeAllProlog((DWORD)pGameTextOut,(DWORD)MystrOut,true_ptr,5); if (!ret) { exit(0); } pstrOut=(int (__cdecl *)(HDC hDC, LPCSTR a2, LPCSTR a3))true_ptr; DebugPrintF("GameTextOut hooked"); перехватывается но в обработчике падает на вызове pstrOut
это со сплайсом начало текстаут игрового Код (Text): 00552E40 $-E9 37062300 JMP vkbd.0078347C 00552E45 . 74 24 JE SHORT game.00552E6B 00552E47 . 14 8B ADC AL,8B 00552E49 . 06 PUSH ES 00552E4A . 8B50 44 MOV EDX,DWORD PTR DS:[EAX+44] 00552E4D . 57 PUSH EDI 00552E4E . 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18] первый прыжок- в мою процедуру/ это оригинал Код (Text): 00552E40 /$ 51 PUSH ECX 00552E41 |. 53 PUSH EBX 00552E42 |. 55 PUSH EBP 00552E43 |. 56 PUSH ESI 00552E44 |. 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14] 00552E48 |. 8B06 MOV EAX,DWORD PTR DS:[ESI] 00552E4A |. 8B50 44 MOV EDX,DWORD PTR DS:[EAX+44] 00552E4D |. 57 PUSH EDI
Напиши по пунктам, что ты хочешь сделать (а лучше нарисуй на бумаге все переходы) - сам увидишь ошибки...
Вот здесь ты куда хочешь попасть? на new_addr? Так, может тогда: JA=(DWORD)new_addr - addr - 5; Формирование bridg тоже не совсем понятно - куда надо прыгнуть? (на addr+prolog_size)? Если с (bridg+prolog_size) надо прыгнуть на (addr + prolog_size), то JA=(addr + prolog_size)-(bridg+prolog_size)-5=addr - bridg - 5;
punxer 0. Где текст обработчега? 1. Если падает в обработчиге (при беглом осмотре перехватчега ошибок не увидел) - можно попробовать максимально его упростить - для начала просто выполнить "стыренные" несколько команд оригинальной функи и прыгнуть / push ret_addr retn в оригинальный код после джампа. Если все регистры после такого возврата целые и стек целый и ничего не сдохло - усложнять...
PSR1257 с пятибайтовым прологом все работает. Код (Text): bool SpliceBridge(__in DWORD addr,__in DWORD new_addr,__out DWORD& true_addr) { DWORD Protects= NULL; DWORD JA= NULL; BYTE* bridg= NULL; if(addr && new_addr) { bridg=(BYTE*)VirtualAlloc(NULL,10,MEM_COMMIT,PAGE_EXECUTE_READWRITE); VirtualProtect((LPVOID)addr, 5, PAGE_EXECUTE_READWRITE, &Protects); ReadProcessMemory(GetCurrentProcess(), (LPVOID)addr, bridg, 5, 0); bridg[5]=0xE9; JA=addr-(DWORD)bridg-5; memcpy(&bridg[6],&JA,4); true_addr=(DWORD)bridg; BYTE jmp[5]={0xE9,0x00,0x00,0x00,0x00}; JA=(DWORD)new_addr - addr - 5; memcpy(&jmp[1],&JA,4); if(WriteProcessMemory(GetCurrentProcess(),(LPVOID)addr,jmp, 5, 0)) { VirtualProtect((LPVOID)addr, 5, Protects, &Protects); return true; } } return false; } нужно модифицировать для пролога любой величины, всмысле начала функции произвольной длины. Код (Text): Код: .text:00552E40 .text:00552E40 ; =============== S U B R O U T I N E ======================================= .text:00552E40 .text:00552E40 .text:00552E40 ; int __cdecl strOut(HDC, LPCSTR, LPCSTR) .text:00552E40 strOut proc near .text:00552E40 .text:00552E40 .text:00552E40 var_4 = dword ptr -4 .text:00552E40 arg_0 = dword ptr 4 .text:00552E40 arg_4 = dword ptr 8 .text:00552E40 arg_8 = dword ptr 0Ch .text:00552E40 .text:00552E40 push ecx .text:00552E41 push ebx .text:00552E42 push ebp .text:00552E43 push esi .text:00552E44 mov esi, [esp+10h+arg_0] .text:00552E48 mov eax, [esi] .text:00552E4A mov edx, [eax+44h] .text:00552E4D push edi .text:00552E4E lea ecx, [esp+14h+arg_0] ; Load Effective Address сдесь джамп разрывает инструкции
1) "Операнд команды jmp является значением со знаком, являющемся смещением переходаотносительно следующей за jmp команды" - вот отсюда и -5 2) Замени расчет смещений (как показано в #14) и поставь prolog_size равным 8 при вызове SpliceBridgeAllProlog 3) Схему jmp-ов нарисовал?