Here it is my first dll written 100% in assembly language(fasm - Flat Assembler) to cheat score in a simple game called LBreakout2 v2.5.1.
Game can be found at http://portableapps.com.
There are 2 addresses for score:
- 0x00475F64 is static and holds the total score;
- [[[[[[004523D4]+0x4394]+0x8]]+0x8]+0x20] holds the score you get with the current ball. When you lose a ball, this score is added to the total score and than zeroed.
The cheat is built upon the second address so that we can learn how to build this expression in asm.
How it works?
Simple:
- Run game and inject the dll using MHS or any other injector.
- Press key "s" during game to add 1kk to score.
- Press key "x" to exit the thread created by the dll and close the dll.
Enjoy,
ctl3d32
Source:
- Code: Select all
; DLL creation example
format PE GUI 4.0 DLL
entry DllEntryPoint
include 'win32a.inc'
section '.text' code readable executable
proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
mov eax,[fdwReason]
cmp eax,DLL_PROCESS_ATTACH
jne .finish
invoke CreateThread,NULL,NULL,CheckScore,NULL,NULL,pid_thread ;Creates a new thead and run function CkechScore that runs in a lool in parallel to the game
mov [h_thread],eax
.finish:
mov eax,TRUE
ret
endp
proc CheckScore
.Loop:
invoke GetAsyncKeyState,0x58 ;check if keyboard x key is pressed
cmp al,1
je .Exit
invoke GetAsyncKeyState,0x53 ;check if keyboard s key is pressed
cmp al,0
je .Loop
invoke FindWindowA,_gclass,_gtitle ;to get the handle of the game window
cmp eax,0
je .Error_FindWindow
mov [h_game_window],eax
invoke GetWindowThreadProcessId,[h_game_window],pid_game_exe ;to get the process id of the game executable
cmp eax,0
je .Error_GetThreadPID
invoke OpenProcess,PROCESS_ALL_ACCESS,NULL,[pid_game_exe] ;to get the handle of the game executable
cmp eax,0
je .Error_OpenProcess
mov [h_game_exe],eax
;Begin - Building the pointer expression [[[[[[004523D4]+0x4394]+0x8]]+0x8]+0x20]
invoke ReadProcessMemory,[h_game_exe],[base],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
mov eax,[p_score]
add eax,4394h
mov [p_score],eax
invoke ReadProcessMemory,[h_game_exe],[p_score],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
mov eax,[p_score]
add eax,8h
mov [p_score],eax
invoke ReadProcessMemory,[h_game_exe],[p_score],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
invoke ReadProcessMemory,[h_game_exe],[p_score],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
mov eax,[p_score]
add eax,8h
mov [p_score],eax
invoke ReadProcessMemory,[h_game_exe],[p_score],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
mov eax,[p_score]
add eax,20h
mov [p_score],eax
invoke ReadProcessMemory,[h_game_exe],[p_score],p_score,4,NULL
cmp eax,0
je .Error_ReadMemory
;End - Building the pointer expression [[[[[[004523D4]+0x4394]+0x8]]+0x8]+0x20]
invoke ReadProcessMemory,[h_game_exe],[p_score],score,4,NULL ;Get the current score value
cmp eax,0
je .Error_ReadMemory
mov eax,[score]
add eax,[add_amount] ;Add 1000000 to the score value
mov [add_amount],eax
invoke WriteProcessMemory,[h_game_exe],[p_score],add_amount,4,NULL ;Write new value to memory
cmp eax,0
je .Error_WriteMemory
;invoke wsprintfA,mtitle,ftitle,[p_score]
;invoke MessageBox,NULL,mtitle,NULL,MB_OK
invoke CloseHandle,[h_game_exe] ;Closes an open object handle opened by OpenProcess
jmp .Loop
.Error_GetThreadPID:
invoke MessageBox,NULL,error_GTPID_text,error_GTPID_title,MB_OK
invoke CloseHandle,[h_game_exe]
jmp .Loop
.Error_FindWindow:
invoke MessageBox,NULL,error_FW_text,error_FW_title,MB_OK
invoke CloseHandle,[h_game_exe]
jmp .Loop
.Error_OpenProcess:
invoke MessageBox,NULL,error_OP_text,error_OP_title,MB_OK
invoke CloseHandle,[h_game_exe]
jmp .Loop
.Error_ReadMemory:
invoke MessageBox,NULL,error_RM_text,error_RM_title,MB_OK
invoke CloseHandle,[h_game_exe]
jmp .Loop
.Error_WriteMemory:
invoke MessageBox,NULL,error_WM_text,error_WM_title,MB_OK
invoke CloseHandle,[h_game_exe]
jmp .Loop
.Exit:
invoke ExitThread,0
endp
section '.data' data readable writeable
_gclass db 'SDL_app',0
_gtitle db 'LBreakout2',0
name db 'lbreakout2.exe',0
error_OP_title db 'Error!',0
error_OP_text db 'Error executing OpenProcess!',0
error_RM_title db 'Error!',0
error_RM_text db 'Error executing WriteMemory!',0
error_WM_title db 'Error!',0
error_WM_text db 'Error executing WriteMemory!',0
error_FW_title db 'Erro!',0
error_FW_text db 'Error executing FindWindow!',0
error_GTPID_title db 'Error!',0
error_GTPID_text db 'Error executing GetThreadProcessID!',0
ftitle db 'p_score is: 0x%p',0
ftext db 'Value is: %ld',0
base dd 004523D4h
add_amount dd 1000000d
section '.bss' readable writeable
pid_thread dd ? ;PID of the new thread
h_thread dd ? ;Handles of the new thread
pid_game_exe dd ? ;PID of the game executable
h_game_window dd ? ;Handles to the game window
h_game_exe dd ? ;Handles to the game executable
p_score dd ? ;Holds the pointer to the score
score dd ? ;Value of score
mtitle rb 400h
mtext rb 400h
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL'
import kernel,\
OpenProcess,'OpenProcess',\
CloseHandle,'CloseHandle',\
ReadProcessMemory,'ReadProcessMemory',\
WriteProcessMemory,'WriteProcessMemory',\
ExitThread,'ExitThread',\
CreateThread,'CreateThread'
import user,\
FindWindowA,'FindWindowA',\
wsprintfA,'wsprintfA',\
GetWindowThreadProcessId,'GetWindowThreadProcessId',\
GetAsyncKeyState,'GetAsyncKeyState',\
MessageBox,'MessageBoxA'
section '.edata' export data readable
export 'LBreakout2v2_5_1.DLL',\
CheckScore,'CheckScore'
section '.reloc' fixups data discardable