gmz

Пишем D3DX9 хак на NASM для Divinity Dragon Commander

1 сообщение в этой теме

2eXpc.png

 

Некоторые особенности:
1 DLL x32 не больше 4кб
2 Никаких внешних костылей
3 Меню\клавиши используют поток игры
4 Меню максимально простое
5 В хаке 8 опций
6 Все секции линкер собирает в .text (кроме .reloc)
7 NASM: http://www.nasm.us/pub/nasm/releasebuilds -> X.XX.XX -> win64 -> nasm-X.XX.XX-win64.zip -> nasm.exe
8 Линкер: ftp://ftp.styx.cabel.net/pub/UniLink -> ulnbXXXX.zip -> ulink.exe
9 Редактор: https://notepad-plus-plus.org/download

 

Приступим...
Создадим txt файл и переименуем в "dragon commander hack.asm"

Открываем файл в notepad++

 

Добавим EntryPoint, структуры, импорт апи

Скрытый текст

global DllMain

struc RECT
.left resd 1
.top resd 1
.right resd 1
.bottom resd 1
endstruc

;kernel32.dll
extern \
__imp_DisableThreadLibraryCalls,\
__imp_CreateThread,\
__imp_CloseHandle,\
__imp_GetModuleHandleW,\
__imp_VirtualProtect,\
__imp_TerminateProcess
;user32.dll
extern \
__imp_GetAsyncKeyState,\
__imp_GetFocus,\
__imp_GetClientRect,\
__imp_MessageBoxW
;d3dx9_43.dll
extern \
__imp_D3DXCreateFontW

 

Создадим секцию кода

Скрытый текст

section .code

Добавим функцию DllMain, resd 1 - для пропуска адреса возврата а ret 3*4 значит что у функции 3 параметра по 4 байта

Скрытый текст

DllMain:
struc .locals
resd 1
.hInstDLL resd 1
.fdwReason resd 1
.lpvReserved resd 1
endstruc
cmp dword[esp+.fdwReason],1
jnz .DLL_PROCESS_ATTACH
push dword[esp+.hInstDLL]
call [__imp_DisableThreadLibraryCalls]
push 0
push 0
push 0
push Init
push 4096
push 0
call [__imp_CreateThread]
push eax
call [__imp_CloseHandle]
mov al,1
.DLL_PROCESS_ATTACH:
ret 3*4

 

Добавляем функцию инициализации, также создадим несколько стек буферов

Скрытый текст

Init:
struc .locals
.exe_base resd 1
.exe_size resd 1
.DX9Binding_base resd 1
.DX9Binding_size resd 1
.Buffer resd 1
alignb 4
endstruc
sub esp,.locals_size

 

Первым делом получаем базу exe игры, размер exe из PE хидера, ставим права на весь модуль

Скрытый текст

lea ebp,[esp+.Buffer]
push 0
call [__imp_GetModuleHandleW]
mov ecx,[eax+60] ;IMAGE_DOS_HEADER.e_lfanew
mov ecx,[eax+ecx+80] ;IMAGE_NT_HEADERS32.OptionalHeader+IMAGE_OPTIONAL_HEADER32.SizeOfImage
mov [esp+.exe_base],eax
mov [esp+.exe_size],ecx
push ebp
push 0x40 ;PAGE_EXECUTE_READWRITE
push ecx
push eax
call [__imp_VirtualProtect]

 

Также DX9Binding.dll, там будем ставить хуки для менюхи. длка загружается на старте игры - добавлять проверку ее наличия не нужно

Скрытый текст

push DX9BindingDLL
call [__imp_GetModuleHandleW]
mov ecx,[eax+60] ;IMAGE_DOS_HEADER.e_lfanew
mov ecx,[eax+ecx+80] ;IMAGE_NT_HEADERS32.OptionalHeader+IMAGE_OPTIONAL_HEADER32.SizeOfImage
mov [esp+.DX9Binding_base],eax
mov [esp+.DX9Binding_size],ecx
push ebp
push 0x40 ;PAGE_EXECUTE_READWRITE
push ecx
push eax
call [__imp_VirtualProtect]

 

Заполним адреса для патчкода (функции, паттерны, адреса - оформим ниже), 2*4/3*4 - фикс сдвига стека

Скрытый текст

push pInstantCallDragon.size
push pInstantCallDragon
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aInstantCallDragon],eax

push pDragonHealth1.size
push pDragonHealth1
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aDragonHealth1],eax

push pDragonHealth2.size
push pDragonHealth2
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aDragonHealth2],eax

push pDragonEnergy.size
push pDragonEnergy
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aDragonEnergy],eax

push pWeaponNoOverheat.size
push pWeaponNoOverheat
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aWeaponNoOverheat],eax

push pWeaponRapidFire.size
push pWeaponRapidFire
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aWeaponRapidFire],eax

push pSkillNoCoolDown.size
push pSkillNoCoolDown
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov [aSkillNoCoolDown],eax

 

Ставим хуки. в даном случае находим адрес, рассчитываем и ставим call, если патчкод был больше 5 байт - добавляем нужное количество NOP, инструкции которые заменил call - добавим в хук функции вручную

Скрытый текст

push pAddGold1.size
push pAddGold1
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov ecx,AddGoldHook1-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx
mov word[eax+5],0x9090

push pAddGold2.size
push pAddGold2
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov ecx,AddGoldHook2-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx
mov word[eax+5],0x9090

push pAddResearchPoints.size
push pAddResearchPoints
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov ecx,AddResearchPointsHook-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx

push pAddResearchPoints.size
push pAddResearchPoints
push dword[esp+.exe_size+2*4]
push dword[esp+.exe_base+3*4]
call FindPattern
mov ecx,AddResearchPointsHook-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx

push pD3DresetDevice.size
push pD3DresetDevice
push dword[esp+.DX9Binding_size+2*4]
push dword[esp+.DX9Binding_base+3*4]
call FindPattern
mov ecx,D3DresetDeviceHook-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx
mov byte[eax+5],0x90

push pD3DEndFrame.size
push pD3DEndFrame
push dword[esp+.DX9Binding_size+2*4]
push dword[esp+.DX9Binding_base+3*4]
call FindPattern
mov ecx,MenuHook-5
sub ecx,eax
mov byte[eax],0xE8 ;call
mov [eax+1],ecx
mov byte[eax+5],0x90

 

Выравниваем стек и завершаем функцию инициализации

Скрытый текст

add esp,.locals_size
ret

Теперь создадим функцию меню. resd 4 нужен для резерва 3 push и 1 ret

Скрытый текст

MenuHook:
struc .locals
resd 4
.D3D_Device resd 1
.Rect resb RECT_size
alignb 4
endstruc
push ebp
push esi
push edi
sub esp,.locals_size

 

Место где установили хук - достает для игры D3D_Device +нам он нужен для D3DXCreateFontW, сохраним его, а в конце функции вернем игре

Скрытый текст

mov eax,[eax+0x138] ;device
mov [esp+.D3D_Device],eax

Добавим функцию для быстрого закрытия игры на кнопку PAUSE

Скрытый текст

push 0x13 ;VK_PAUSE
call [__imp_GetAsyncKeyState]
test ah,ah
jz .SkipCloseGame
push 0
push -1
call [__imp_TerminateProcess]
.SkipCloseGame:

 

Добавим код для проверки активности окна. Также код используется для получения hGameWnd, следовательно, после инжекта, меню нарисуется только после клика в окно

Скрытый текст

call [__imp_GetFocus]
cmp dword[hGameWnd],0
jnz .FirstClick
mov [hGameWnd],eax
jmp .SkipDraw
.FirstClick:
cmp [hGameWnd],eax
jnz .SkipKeys

 

Добавим кнопку скрыть/показать меню. cmp + setz = 0/1 aka вкл/откл

Скрытый текст

push 0x2D ;VK_INSERT
call [__imp_GetAsyncKeyState]
cmp [kMenu+1],ah
jz .Menu
mov [kMenu+1],ah
test ah,ah
jz .Menu
cmp byte[kMenu],0
setz [kMenu]
.Menu:

 

Добавляем все опции, включая опции для которых нужен патчкод

Скрытый текст

push 0x61 ;VK_NUMPAD1
call [__imp_GetAsyncKeyState]
cmp [kAddGold+1],ah
jz .AddGold
mov [kAddGold+1],ah
test ah,ah
jz .AddGold
cmp byte[kAddGold],0
setz [kAddGold]
.AddGold:

push 0x62 ;VK_NUMPAD2
call [__imp_GetAsyncKeyState]
cmp [kAddResearchPoints+1],ah
jz .AddResearchPoints
mov [kAddResearchPoints+1],ah
test ah,ah
jz .AddResearchPoints
cmp byte[kAddResearchPoints],0
setz [kAddResearchPoints]
.AddResearchPoints:

push 0x63 ;VK_NUMPAD3
call [__imp_GetAsyncKeyState]
cmp [kInstantCallDragon+1],ah
jz .InstantCallDragon
mov [kInstantCallDragon+1],ah
test ah,ah
jz .InstantCallDragon
cmp byte[kInstantCallDragon],0
setz [kInstantCallDragon]
push bInstantCallDragon.size
push bInstantCallDragon
push dword[aInstantCallDragon]
call MemSwap
.InstantCallDragon:

push 0x64 ;VK_NUMPAD4
call [__imp_GetAsyncKeyState]
cmp [kDragonHealth+1],ah
jz .DragonHealth
mov [kDragonHealth+1],ah
test ah,ah
jz .DragonHealth
cmp byte[kDragonHealth],0
setz [kDragonHealth]
push bDragonHealth1.size
push bDragonHealth1
push dword[aDragonHealth1]
call MemSwap
push bDragonHealth2.size
push bDragonHealth2
push dword[aDragonHealth2]
call MemSwap
.DragonHealth:

push 0x65 ;VK_NUMPAD5
call [__imp_GetAsyncKeyState]
cmp [kDragonEnergy+1],ah
jz .DragonEnergy
mov [kDragonEnergy+1],ah
test ah,ah
jz .DragonEnergy
cmp byte[kDragonEnergy],0
setz [kDragonEnergy]
push bDragonEnergy.size
push bDragonEnergy
push dword[aDragonEnergy]
call MemSwap
.DragonEnergy:

push 0x66 ;VK_NUMPAD6
call [__imp_GetAsyncKeyState]
cmp [kWeaponNoOverheat+1],ah
jz .WeaponNoOverheat
mov [kWeaponNoOverheat+1],ah
test ah,ah
jz .WeaponNoOverheat
cmp byte[kWeaponNoOverheat],0
setz [kWeaponNoOverheat]
push bWeaponNoOverheat.size
push bWeaponNoOverheat
push dword[aWeaponNoOverheat]
call MemSwap
.WeaponNoOverheat:

push 0x67 ;VK_NUMPAD7
call [__imp_GetAsyncKeyState]
cmp [kWeaponRapidFire+1],ah
jz .WeaponRapidFire
mov [kWeaponRapidFire+1],ah
test ah,ah
jz .WeaponRapidFire
cmp byte[kWeaponRapidFire],0
setz [kWeaponRapidFire]
push bWeaponRapidFire.size
push bWeaponRapidFire
push dword[aWeaponRapidFire]
call MemSwap
.WeaponRapidFire:

push 0x68 ;VK_NUMPAD8
call [__imp_GetAsyncKeyState]
cmp [kSkillNoCoolDown+1],ah
jz .SkillNoCoolDown
mov [kSkillNoCoolDown+1],ah
test ah,ah
jz .SkillNoCoolDown
cmp byte[kSkillNoCoolDown],0
setz [kSkillNoCoolDown]
push bSkillNoCoolDown.size
push bSkillNoCoolDown
push dword[aSkillNoCoolDown]
call MemSwap
.SkillNoCoolDown:

 

После опций, добавим код создания шрифта и получения размера видимой области окна, также передвинем меню в правый угол

Скрытый текст

.SkipKeys:
cmp byte[kMenu],0
jnz .SkipDraw
cmp dword[hFont],0
jnz .SkipCreateFont
push hFont
push Font
push 0 ;DEFAULT_PITCH
push 2 ;PROOF_QUALITY
push 0 ;OUT_DEFAULT_PRECIS
push 1 ;DEFAULT_CHARSET
push 0
push 0
push 0x2BC ;FW_BOLD
push 0
push 16 ;size
push dword[esp+.D3D_Device+11*4]
call [__imp_D3DXCreateFontW]
push Rect
push dword[hGameWnd]
call [__imp_GetClientRect]
add dword[Rect+RECT.top],3
mov eax,[Rect+RECT.right]
sub eax,182
mov [Rect+RECT.left],eax
sub dword[Rect+RECT.right],6
.SkipCreateFont:
lea ebp,[esp+.Rect]
mov ecx,RECT_size/4
mov esi,Rect
mov edi,ebp
cld
rep movsd
mov esi,[hFont]
mov edi,[esi] ;pointers d3dx9core.h

 

Для вывода текста опций - используем DrawTextW

Скрытый текст

cmp byte[kAddGold],0
jz .AddGoldDisable
push 0xFFFF0000 ;red
jmp .AddGoldEnable
.AddGoldDisable:
push 0xFF1C9ADB ;blue
.AddGoldEnable:
push 0x100 ;DT_NOCLIP
push ebp
push AddGold.size
push AddGold
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kAddResearchPoints],0
jz .AddResearchPointsDisable
push 0xFFFF0000 ;red
jmp .AddResearchPointsEnable
.AddResearchPointsDisable:
push 0xFF1C9ADB ;blue
.AddResearchPointsEnable:
push 0x100 ;DT_NOCLIP
push ebp
push AddResearchPoints.size
push AddResearchPoints
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kInstantCallDragon],0
jz .InstantCallDragonDisable
push 0xFFFF0000 ;red
jmp .InstantCallDragonEnable
.InstantCallDragonDisable:
push 0xFF1C9ADB ;blue
.InstantCallDragonEnable:
push 0x100 ;DT_NOCLIP
push ebp
push InstantCallDragon.size
push InstantCallDragon
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kDragonHealth],0
jz .DragonHealthDisable
push 0xFFFF0000 ;red
jmp .DragonHealthEnable
.DragonHealthDisable:
push 0xFF1C9ADB ;blue
.DragonHealthEnable:
push 0x100 ;DT_NOCLIP
push ebp
push DragonHealth.size
push DragonHealth
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kDragonEnergy],0
jz .DragonEnergyDisable
push 0xFFFF0000 ;red
jmp .DragonEnergyEnable
.DragonEnergyDisable:
push 0xFF1C9ADB ;blue
.DragonEnergyEnable:
push 0x100 ;DT_NOCLIP
push ebp
push DragonEnergy.size
push DragonEnergy
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kWeaponNoOverheat],0
jz .WeaponNoOverheatDisable
push 0xFFFF0000 ;red
jmp .WeaponNoOverheatEnable
.WeaponNoOverheatDisable:
push 0xFF1C9ADB ;blue
.WeaponNoOverheatEnable:
push 0x100 ;DT_NOCLIP
push ebp
push WeaponNoOverheat.size
push WeaponNoOverheat
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kWeaponRapidFire],0
jz .WeaponRapidFireDisable
push 0xFFFF0000 ;red
jmp .WeaponRapidFireEnable
.WeaponRapidFireDisable:
push 0xFF1C9ADB ;blue
.WeaponRapidFireEnable:
push 0x100 ;DT_NOCLIP
push ebp
push WeaponRapidFire.size
push WeaponRapidFire
push 0
push esi
call [edi+60] ;DrawTextW
add [esp+.Rect+RECT.top],eax

cmp byte[kSkillNoCoolDown],0
jz .SkillNoCoolDownDisable
push 0xFFFF0000 ;red
jmp .SkillNoCoolDownEnable
.SkillNoCoolDownDisable:
push 0xFF1C9ADB ;blue
.SkillNoCoolDownEnable:
push 0x100 ;DT_NOCLIP
push ebp
push SkillNoCoolDown.size
push SkillNoCoolDown
push 0
push esi
call [edi+60] ;DrawTextW

add eax,4
add [esp+.Rect+RECT.top],eax
push 0xFF1C9ADB ;blue
push 0x2+0x100 ;DT_RIGHT+DT_NOCLIP
push ebp
push About.size
push About
push 0
push esi
call [edi+60] ;DrawTextW

 

Возвращаем игре D3D_Device, выравниваем стек, восстанавливаем важные регистры и ставим ret для возврата на код игры

Скрытый текст

.SkipDraw:
mov eax,[esp+.D3D_Device]
add esp,.locals_size
pop edi
pop esi
pop ebp
ret

 

Теперь добавляем функцию поиска. Она не особо сложная, очень быстрая и может пропускать мусорные байты.

Скрытый текст

FindPattern:
struc .locals
resd 5
.Buffer resd 1
.BufferSize resd 1
.Pattern resd 1
.PatternSize resd 1
endstruc
push ebx
push ebp
push esi
push edi
mov eax,[esp+.Buffer]
mov ebp,[esp+.BufferSize]
mov esi,[esp+.Pattern]
mov edi,[esp+.PatternSize]
mov bh,[esi]
add ebp,eax
add edi,esi
jmp .Start
.Check1:
mov ecx,esi
mov edx,eax
.Check2:
add ecx,1
.Check3:
add edx,1
cmp edi,ecx
jz .Found
cmp ebp,edx
jz .Fail
cmp word[ecx],0xDEAD
jnz .Skip
add ecx,2
jmp .Check3
.Skip:
mov bl,[edx]
cmp bl,[ecx]
jz .Check2
.Next:
add eax,1
cmp ebp,eax
jz .Fail
.Start:
cmp [eax],bh
jnz .Next
jmp .Check1
.Fail:
push 0x10+0x40000 ;MB_ICONERROR+MB_TOPMOST
push 0
push PatternFail
push 0
call [__imp_MessageBoxW]
push 0
push -1
call [__imp_TerminateProcess]
.Found:
pop edi
pop esi
pop ebp
pop ebx
ret 4*4

 

и функцию обмена байтами, чтобы не копировать оригинал код для откл опций

Скрытый текст

MemSwap:
struc .locals
resd 2
.Address resd 1
.Patch resd 1
.Size resd 1
endstruc
push ebx
mov eax,[esp+.Address]
mov ecx,[esp+.Patch]
mov edx,[esp+.Size]
.Next:
sub edx,1
mov bh,[eax+edx]
mov bl,[ecx+edx]
mov [eax+edx],bl
mov [ecx+edx],bh
jnz .Next
pop ebx
ret 3*4

 

и самую важную часть - освобождение ресурсов которые были созданы D3DXCreateFontW, если их не освободить - игра просто вылелит в момент изменения размера окна. Обнуление hFont нужно чтобы D3DXCreateFontW смог создать новый шрифт +получить новый размер окна

Скрытый текст

D3DresetDeviceHook:
push eax
push ecx
push edx
cmp dword[hFont],0
jz .Skip
mov eax,[hFont]
mov ecx,[eax] ;pointers d3dx9core.h
push eax
call [ecx+8] ;ReleaseFont
mov [hFont],eax ;0
.Skip:
pop edx
pop ecx
pop eax
mov edi,ecx
mov [esp+0x10+0x4],ebx ;+4 hook
ret

 

и остальные функции для обработки перехвата. там также находится "оригинал код" который был заменен на call

Скрытый текст

AddGoldHook1:
mov [esp+0x20+0x4],eax ;+4 call
cmp byte[kAddGold],0
jz .Skip
mov dword[eax+0x3C],1000
.Skip:
mov eax,[eax+0x3C]
ret

AddGoldHook2:
cmp byte[kAddGold],0
jz .SkipAddGold
mov dword[ecx+edx*4+0x480],100000
.SkipAddGold:
mov ecx,[ecx+edx*4+0x480]
ret

AddResearchPointsHook:
cmp byte[kAddResearchPoints],0
jz .Skip
mov dword[eax+0x44],1000
.Skip:
mov edx,[eax+0x44]
pop ecx ;ret
push edx
push ecx
lea ecx,[esp+0x5C+0x4] ;+4 ret
ret

 

Создадим секцию данных для: паттернов, патчкода, строк

Скрытый текст

section .data
pD3DEndFrame db 0x8B,0x80,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x8B,0x08,0x8B,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x50,0xFF,0xD2,0x8B ;8B 80 ?? ?? ?? ?? 8B 08 8B ?? ?? ?? ?? ?? 50 FF D2 8B
.size equ $-pD3DEndFrame
pD3DresetDevice db 0x8B,0xF9,0x89,0x5C,0xAD,0xDE,0xAD,0xDE,0x39 ;8B F9 89 5C ?? ?? 39
.size equ $-pD3DresetDevice
pAddGold1 db 0x89,0x44,0x24,0xAD,0xDE,0x8B,0x40,0x3C,0x50 ;89 44 24 ?? 8B 40 3C 50
.size equ $-pAddGold1
pAddGold2 db 0x8B,0x8C,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x89,0x44,0xAD,0xDE,0xAD,0xDE,0x89,0x4C,0xAD,0xDE,0xAD,0xDE,0x39 ;8B 8C ?? ?? ?? ?? ?? 89 44 ?? ?? 89 4C ?? ?? 39
.size equ $-pAddGold2
pAddResearchPoints db 0x52,0x8D,0x4C,0x24,0xAD,0xDE,0xFF,0x15,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x6A,0x06 ;52 8D 4C 24 ?? FF 15 ?? ?? ?? ?? 6A 06
.size equ $-pAddResearchPoints
pInstantCallDragon db 0x2B,0xC8,0x89,0x8E,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x79 ;2B C8 89 8E ?? ?? ?? ?? 79
.size equ $-pInstantCallDragon
pDragonHealth1 db 0x7D,0xAD,0xDE,0x8B,0x44,0x24,0x34,0x8B,0x0F,0xD9 ;7D ?? 8B 44 24 34 8B 0F D9
.size equ $-pDragonHealth1
pDragonHealth2 db 0x7D,0x06,0xD8,0x05,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xD8,0x35,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xD9,0x5C,0xAD,0xDE,0xAD,0xDE,0xD9,0x44,0xAD,0xDE,0xAD,0xDE,0xD8,0x4D ;7D 06 D8 05 ?? ?? ?? ?? D8 35 ?? ?? ?? ?? D9 5C ?? ?? D9 44 ?? ?? D8 4D
.size equ $-pDragonHealth2
pDragonEnergy db 0x7A,0x06,0xD9,0x47,0xAD,0xDE,0xD9,0x5F,0xAD,0xDE,0x8B ;7A 06 D9 47 ?? D9 5F ?? 8B
.size equ $-pDragonEnergy
pWeaponNoOverheat db 0xD9,0x87,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xD8,0x87,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xD9,0x9F,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xD9,0x87 ;D9 87 ?? ?? ?? ?? D8 87 ?? ?? ?? ?? D9 9F ?? ?? ?? ?? D9 87
.size equ $-pWeaponNoOverheat
pWeaponRapidFire db 0xE8,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0xAD,0xDE,0x3B,0xF0,0x7C,0x16,0x2B ;E8 ?? ?? ?? ?? 3B F0 7C 16 2B
.size equ $-pWeaponRapidFire
pSkillNoCoolDown db 0x2B,0xC8,0x89,0x0E,0x79,0x06,0xC7 ;2B C8 89 0E 79 06 C7
.size equ $-pSkillNoCoolDown

bInstantCallDragon db 0x29,0xC9
.size equ $-bInstantCallDragon
bDragonHealth1 db 0xEB
.size equ $-bDragonHealth1
bDragonHealth2 db 0x74
.size equ $-bDragonHealth2
bDragonEnergy db 0x70
.size equ $-bDragonEnergy
bWeaponNoOverheat db 0xD9,0xEE,0x90,0x90,0x90,0x90
.size equ $-bWeaponNoOverheat
bWeaponRapidFire db 0xB8,0x20,0x4E,0x00,0x00
.size equ $-bWeaponRapidFire
bSkillNoCoolDown db 0x29,0xC9
.size equ $-bSkillNoCoolDown

align 4,db 0
DX9BindingDLL dw __utf16__'DX9Binding.dll',0
align 4,db 0
Font dw __utf16__'Arial',0
align 4,db 0
PatternFail dw __utf16__'Game version unsupported!',0
align 4,db 0
AddGold dw __utf16__'NUM1 Add Gold',0
.size equ ($-AddGold-2)/2
align 4,db 0
AddResearchPoints dw __utf16__'NUM2 Add Research Points',0
.size equ ($-AddResearchPoints-2)/2
align 4,db 0
InstantCallDragon dw __utf16__'NUM3 Instant Call Dragon',0
.size equ ($-InstantCallDragon-2)/2
align 4,db 0
DragonHealth dw __utf16__'NUM4 Dragon Health',0
.size equ ($-DragonHealth-2)/2
align 4,db 0
DragonEnergy dw __utf16__'NUM5 Dragon Energy',0
.size equ ($-DragonEnergy-2)/2
align 4,db 0
WeaponNoOverheat dw __utf16__'NUM6 Weapon No Overheat',0
.size equ ($-WeaponNoOverheat-2)/2
align 4,db 0
WeaponRapidFire dw __utf16__'NUM7 Weapon Rapid Fire',0
.size equ ($-WeaponRapidFire-2)/2
align 4,db 0
SkillNoCoolDown dw __utf16__'NUM8 Skill No CoolDown',0
.size equ ($-SkillNoCoolDown-2)/2
align 4,db 0
About dw __utf16__'by gmz',0
.size equ ($-About-2)/2

 

Создадим секцию неинициализ. даных (они не занимают физически место в длке)

Скрытый текст

section .bss
hGameWnd resd 1
hFont resd 1
Rect resb RECT_size
aInstantCallDragon resd 1
aDragonHealth1 resd 1
aDragonHealth2 resd 1
aDragonEnergy resd 1
aWeaponNoOverheat resd 1
aWeaponRapidFire resd 1
aSkillNoCoolDown resd 1
kMenu resb 2
kAddGold resb 2
kAddResearchPoints resb 2
kInstantCallDragon resb 2
kDragonHealth resb 2
kDragonEnergy resb 2
kWeaponNoOverheat resb 2
kWeaponRapidFire resb 2
kSkillNoCoolDown resb 2

 

 

Сборка:

Скрытый текст

..\nasm\nasm.exe -f win32 "dragon commander hack.asm"
..\nasm\ulink.exe -q -Z- -w- -ZX- -W6.0 -U6.0 -V6.0 -S:0x1000 -Sc:0x1000 -H:0x10000 -Hc:0x0 -GF:NXCOMPAT -Gh -Gz -Ge -GS:*=* -aa -Tpd -b:0x10000000* -eDllMain "dragon commander hack.obj" kernel32.dll user32.dll d3dx9_43.dll

ps описание всех опций линкера находится в его справке.

 

Изменено пользователем gmz
5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас