PDA

View Full Version : ASM Trainer Skeleton (Beware ive not written this well :P)


DABhand
26-08-2005, 16:56
http://www.vwaskar.pwp.blueyonder.co.uk/asm4FF/asmtrain.txt if you want to read as it is


Here it comes

Building an ASM Trainer from a Skeleton Build
=============================================


Needed-

1. MASM (http://www.masm32.com/)
2. Trainer Skeleton Build (http://www.vwaskar.pwp.blueyonder.co.uk/asm4FF/trainerasm.rar - Thanks Sheep for releasing this ;) )
3. Helps to know basic ASM at least :P



Ok why an ASM trainer and not using TMK or other easy to build trainer programs, well ASM has a huge size advantage..


For example

A trainer done in ASM can be around 50-70k size, 20-40k with an external packer.

A trainer done in TMK (same bitmaps,etc) will be around 200k+ compressed with its own packer.


And lets not forget TMK trainers usually cause AV scanners to go mad of trojan warnings when there isnt one lol


Ok lets get started....



1. MASM


Yep goto the site above and download MASM 8.2 and install it


Do please leave it to its default install folder for now, will be easier to use the skeleton code to do your trainer


So when thats done (it may take a while depending on your machine specs)


2. Skeleton Code


Download the skeleton trainer from my webspace, unfortunately for now Sheep's site has closed for a while :\ so ill host
in the mean time :) Im sure he wont mind..


Unpack the file to say c:\trainers\ or whatever you prefer.



3. Lets analyse...


Well lets start from the top, open up trainer.asm file in your skeleton folder...


; ********************************
; * PGC Trainer Code *
; ********************************
; * *
; * Code : [sheep] *
; * date : 08.26.01 *
; * language : asm *
; * *
; ********************************

;.GO.
;################################################# ###############################

.386
.model flat,stdcall
option casemap:none



Top off course is Sheep's little signature, anything you want to add to the coding to explain anything start with a ;
this will make sure when the coding is compiled it will ignore these as instructions and wont compile it ;)

.386 - Model version of your CPU, 386's are really old lol basically this means this can be run on a very early 386
processor and above you can offcourse set to 586 or 486 etc, but to make it more available to others just use 386.


.model flat - A program written in native 32 bit Windows format is created in what is called FLAT memory model which has a single
segment that contains both code and data. The programs must be run on a 386 or higher processor.

Differing from earlier 16 bit code that used combined segment and offset addressing with a 64k segment limit, FLAT
memory model works only in offsets and has a range of 4 gigabytes. This makes assembler easier to write and the code
is generally a lot faster.

All segment registers are automatically set to the same value with this memory model and this means that segment / offset
addressing must NOT be used in 32 bit programs that run in 32 bit Windows.

For programmers who have written code in DOS, a 32 bit Windows PE executable file is similar in some respects to a dos
COM file, they have a single segment that can contain both code and data and they both work directly in offsets, neither
use Segment / Offset addressing.

The defaults in flat-model programs are NEAR code addressing and NEAR data addressing within the range of 4 gigabytes.

The FS and GS segment registers are not normally used in application programs but are used in some instances by the
operating system. (Taken from masm32 help docs, as it was easier to explain lol)


stdcall - Calling Convention, this is best explained by searching for it on the net, if you want to :P


casemap:none - Case Sensitive Control, set to none, if set to ALL it makes all lower case characters upper case.


I.E. Best leave these settings as is ;)


Next
----


;.LIBS AND INCS.
;################################################# ###############################

DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD


include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib\masm32\lib\user32.lib
includelib\masm32\lib\kernel32.lib



For a more detailed idea on what is happening here, check the masm32 help docs.


But basically your telling which API's your going to use in your program. If you dont include them
any API you use later will not be recognised, and will result in the coding not being compiled.


Next
----


The fun bit :P


;.DATA.
;################################################# ###############################

.data
DlgName db "MyDialog",0
AppName db "Pizza Trainer v1.10",0
bufferw db 65 dup (0)


infocap db "INFO",0

infomessage db "TITLE............: Doulber Escape From The 80's ",0ah
db "VERSION......: ?? ",0ah
db "TRAINER....: crayola ",0ah
db "CODE............: crayola ",0ah
db "QUOTE.........: 'LUV not WAR' ",0h

errorcap db "ERROR",0

errormessage db "COULD NOT OPEN PROCESS!!!",0ah
db " ",0ah
db "MAKE SURE TRAINER IS IN ",0ah
db "SAME DIRECTORY AS THE ",0ah
db "GAME. ",0h

detectcap db "ERROR",0

detectmessage db " ",0ah
db " GAME IS NOT LOADED!!!",0ah
db " ",0h





Gaddress1 dd 0040cdd3h
Gval1 db 090h,090h,090h,090h,090h,090h
Gnum1 db 6

Gaddress2 dd 0040d84fh
Gval2 db 090h,090h
Gnum2 db 2

Gaddress3 dd 0040900eh
Gval3 db 0c6h,083h,05eh,014h,001h,000h,000h,090h
Gnum3 db 8

Gaddress4 dd 0040cd10h
Gval4 db 0e9h,009h,001h,000h,000h,090h
Gnum4 db 6

Gaddress5 dd 00478020h
Gval5 db 080h,03dh,050h,080h,047h,000h,001h,00fh,085h,0d7h, 09eh,0f8h,0ffh,0c6h,005h,050h,080h,047h,000h,000h, 0e9h,038h,09eh,0f8h,0ffh
Gnum5 db 25

Gaddress5_2 dd 00401e6bh
Gval5_2 db 0e9h,0b0h,061h,007h,000h,090h
Gnum5_2 db 6

Gaddress5_3 dd 00478050h
Gval5_3 db 001h
Gnum5_3 db 1

g5_flag db 0

bytes_written dw 0
FileName db "game.exe",0
flag_loaded db 0
Flag_@error db 0
Hwnd dd 0



.data?
StartUpInfo STARTUPINFO <>
hProcess dd ?
hInstance HINSTANCE ?
CommandLine LPSTR ?
buffer db 512 dup(?)
buffer2 dd ?


.const
IDC_EDIT equ 3000
IDC_BUTTON equ 3001
IDC_EXIT equ 3002
IDM_GETTEXT equ 32000
IDM_CLEAR equ 32001
IDM_EXIT equ 32002
ID_TIMER1 equ 4000


This is the area where you declare any variables your going to use and any possible values included.


DlgName db "MyDialog",0 - the db part means it will allocate each character by byte, anything involving text will have
db used. dw = word (2 bytes) dd = dword (4 bytes) others can be checked in the help files.

This is just setting the Dialogue name of the trainer to "MyDialog". The 0 at the end, just
terminates the line, as in no more to show.


AppName db "Pizza Trainer v1.10",0 - This sets what it will show in Title Bar of the trainer.


bufferw db 65 dup (0) - Just setting a buffer size here, dont worry about this, leave as is.


Next parts is setting error messages, which is quite straight forward. The 0ah means new line (i.e. as if the return has been pressed),
again with 0h at the end to terminate the line. h is hex incase you forgot :P


Gaddress1 dd 0040cdd3h - Address at which to write data
Gval1 db 090h,090h,090h,090h,090h,090h - What data to write, in hex offcourse
Gnum1 db 6 - Size of data to be written (in decimal - dec for short)


This is where you place your own code injections or code patching, always start with your code cave first then the amended game code after.
Or else the game will crash since it cant find opcodes to use.


bytes_written dw 0
FileName db "game.exe",0
flag_loaded db 0
Flag_@error db 0
Hwnd dd 0


Just more variables we set up, one more important


FileName db "game.exe",0 - whats the games exe name?


The rest, except Hwnd, are byte values with the value of 0 assigned to them.

The next area are undefined values, which will be defined when the trainer is run. Again dont worry about this at the moment.


.const
IDC_EDIT equ 3000
IDC_BUTTON equ 3001
IDC_EXIT equ 3002
IDM_GETTEXT equ 32000
IDM_CLEAR equ 32001
IDM_EXIT equ 32002
ID_TIMER1 equ 4000

Here we are setting constant values, i.e. values that will never change at all. Whats EQU?


IDC_EDIT equ 3000


EQU evaluates the numeric value of 3000 and assigns the resulting constant value to IDC_EDIT.
EQU does not allow numeric equates to be redefined (i.e 3+4=7), you can however have 3+4 and it will
work out the value 7 for you.

If the value (3000) cannot be evaluated, EQU treats the value as text.


Basically we are setting, in this case, offset values for later.


Now onto the .code section



.code

start:

invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam, hInstance, 100,NULL,addr DlgProc,NULL
invoke ExitProcess,eax


DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM


.IF uMsg==WM_INITDIALOG
mov eax,hWnd
mov Hwnd,eax
invoke GetDlgItem, hWnd,200
invoke SetFocus,eax
invoke SetTimer,hWnd,ID_TIMER1,80,NULL
call @keyboardflush

.ELSEIF uMsg==WM_CLOSE
invoke ExitProcess,0

.ELSEIF uMsg==WM_TIMER
cmp wParam,ID_TIMER1
jnz @next_timer

invoke GetAsyncKeyState,"1"
cmp eax,0
jz @key2
cmp flag_loaded,1
jz @startf1
call error1
jmp @next_timer
@startf1:
;int 3
invoke WriteProcessMemory,hProcess,Gaddress1,addr Gval1,Gnum1,bytes_written

@key2:

invoke GetAsyncKeyState,"2"
cmp eax,0
jz @key3
cmp flag_loaded,1
jz @startf2
call error1
jmp @next_timer
@startf2:
invoke WriteProcessMemory,hProcess,Gaddress2,addr Gval2,Gnum2,bytes_written


@key3:
invoke GetAsyncKeyState,"3"
cmp eax,0
jz @key4
cmp flag_loaded,1
jz @startf3
call error1
jmp @next_timer

@startf3:
invoke WriteProcessMemory,hProcess,Gaddress3,addr Gval3,Gnum3,bytes_written


@key4:

invoke GetAsyncKeyState,"4"
cmp eax,0
jz @key5
cmp flag_loaded,1
jz @startf4
call error1
jmp @next_timer
@startf4:

invoke WriteProcessMemory,hProcess,Gaddress4,addr Gval4,Gnum4,bytes_written


@key5:

invoke GetAsyncKeyState,"5"
cmp eax,0
jz @next_timer
cmp flag_loaded,1
jz @startf5
call error1
jmp @next_timer
@startf5:

cmp g5_flag,0
jnz @set1

invoke WriteProcessMemory,hProcess,Gaddress5,addr Gval5,Gnum5,bytes_written
invoke WriteProcessMemory,hProcess,Gaddress5_2,addr Gval5_2,Gnum5_2,bytes_written
@set1:
invoke WriteProcessMemory,hProcess,Gaddress5_3,addr Gval5_3,Gnum5_3,bytes_written
mov g5_flag,1



@next_timer:

.ELSEIF uMsg==WM_COMMAND
mov eax,wParam

.IF lParam==0
.ELSE
mov edx,wParam
shr edx,16

.IF dx==BN_CLICKED

.IF ax==101

invoke CreateProcess, ADDR FileName, NULL,NULL,NULL,NULL,\
NORMAL_PRIORITY_CLASS,NULL,NULL,ADDR StartUpInfo,ADDR hProcess
cmp eax,0
jnz loaded_ok

invoke MessageBoxA,hWnd,ADDR errormessage,ADDR errorcap,64
jmp @errorexit

loaded_ok:
mov flag_loaded,1

@errorexit:
.ELSEIF ax==102

invoke MessageBoxA,hWnd,ADDR infomessage,ADDR infocap,64

.ELSEIF ax==IDC_EXIT

invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0
.ENDIF
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF

mov eax,TRUE
ret
DlgProc endp


error1 proc

cmp Flag_@error,0
jnz @end1
mov Flag_@error,1
invoke MessageBoxA,Hwnd,ADDR detectmessage,ADDR detectcap,64
mov Flag_@error,0

@end1:
ret

error1 endp

@keyboardflush proc

;invoke GetAsyncKeyState,VK_F1
;invoke GetAsyncKeyState,VK_F2
;invoke GetAsyncKeyState,VK_F3
;invoke GetAsyncKeyState,VK_F4
;invoke GetAsyncKeyState,VK_F5
;invoke GetAsyncKeyState,VK_F6
;invoke GetAsyncKeyState,VK_F7
;invoke GetAsyncKeyState,VK_F8
;invoke GetAsyncKeyState,VK_F9

invoke GetAsyncKeyState,"1"
invoke GetAsyncKeyState,"2"
invoke GetAsyncKeyState,"3"
invoke GetAsyncKeyState,"4"
invoke GetAsyncKeyState,"5"
;invoke GetAsyncKeyState,"6"
;invoke GetAsyncKeyState,"7"
;invoke GetAsyncKeyState,"8"
;invoke GetAsyncKeyState,"9"
;invoke GetAsyncKeyState,"0"

ret

@keyboardflush endp


end start



Quite long huh :P


Lets get to the more important part


.ELSEIF uMsg==WM_TIMER
cmp wParam,ID_TIMER1 - Timer run out?
jnz @next_timer - Goto next timer coding

invoke GetAsyncKeyState,"1" - Check the state of the key 1, if been pressed or not
cmp eax,0 - Was the key pressed?
jz @key2 - If not jump to @key2 section
cmp flag_loaded,1 - Has the game been loaded yet?
jz @startf1 - If yes jump to @startf1 section
call error1 - If not call error msg that game is not loaded
jmp @next_timer - Jump to @next_timer section
@startf1:
;int 3
invoke WriteProcessMemory,hProcess,Gaddress1,addr Gval1,Gnum1,bytes_written - Write values to address



Its pretty much the same for the rest.

If you had just 1 option, you could do this


invoke GetAsyncKeyState,"1"
cmp eax,0
jz @next_timer
....etc


Since there is no more keys, you would just goto the @next time section to loop the trainer again.



Next is this


.IF dx==BN_CLICKED - Was mouse button clicked?

.IF ax==101 - Was it on the button ID 101 (this is our run game)

invoke CreateProcess, ADDR FileName, NULL,NULL,NULL,NULL,\
NORMAL_PRIORITY_CLASS,NULL,NULL,ADDR StartUpInfo,ADDR hProcess - If so Load the game executable
cmp eax,0 - Load ok?
jnz loaded_ok - If so goto loaded_ok section, if not..

invoke MessageBoxA,hWnd,ADDR errormessage,ADDR errorcap,64 - show error msg window
jmp @errorexit - jmp to @errorexit...

loaded_ok:
mov flag_loaded,1 - Move the value 1 to flag_loaded variable (remember this when checking keys?)

@errorexit:
.ELSEIF ax==102 - Or was the button ID 102 (Info) pressed?

invoke MessageBoxA,hWnd,ADDR infomessage,ADDR infocap,64 - If so show our info window

.ELSEIF ax==IDC_EXIT - Have they pressed the OK button on either window?

invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0 - If so close window.
.ENDIF


I know it looks difficult, but search the net for these API's and their functions


CreateProcess
MessageBoxA
SendMessage
GetAsyncKeyState



@keyboardflush proc

;invoke GetAsyncKeyState,VK_F1
;invoke GetAsyncKeyState,VK_F2
;invoke GetAsyncKeyState,VK_F3
;invoke GetAsyncKeyState,VK_F4
;invoke GetAsyncKeyState,VK_F5
;invoke GetAsyncKeyState,VK_F6
;invoke GetAsyncKeyState,VK_F7
;invoke GetAsyncKeyState,VK_F8
;invoke GetAsyncKeyState,VK_F9

invoke GetAsyncKeyState,"1"
invoke GetAsyncKeyState,"2"
invoke GetAsyncKeyState,"3"
invoke GetAsyncKeyState,"4"
invoke GetAsyncKeyState,"5"
;invoke GetAsyncKeyState,"6"
;invoke GetAsyncKeyState,"7"
;invoke GetAsyncKeyState,"8"
;invoke GetAsyncKeyState,"9"
;invoke GetAsyncKeyState,"0"

ret

This section just sets out what keys are used, and flushes their values. Just change to whatever your using for your keys in the trainer,
i.e. change "1" to "A" to use A, etc. If you want to use SHIFT+1, check the net for how to set this, likewise for CTRL and ALT :)



Ok, I know it seems WOOOOAHHHHHHH but im tired and im trying to make it easy :P


Just change the necessary areas, like AppName, The error messages, the Info messages, The address+values of your code injection/patching


Also if using different keys, make sure in each section to write the data that you tell it which key you pressed.

for example


invoke GetAsyncKeyState,"A"
cmp eax,0
....etc


Once your done save your .asm file as something like "gamename.asm" gamename being your game your training.



Now.... Load up Rsrc.rc file into notepad... you will get this...




/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

100 DIALOG DISCARDABLE 0, 0, 236, 154
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Trainer v1.10"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "Run Game",101,10,93,50,14
DEFPUSHBUTTON "About!",102,178,93,50,14
CONTROL 113,IDC_STATIC,"Static",SS_BITMAP | WS_BORDER,4,7,229,43
GROUPBOX "Trainer Options :",IDC_STATIC,65,60,108,77
LTEXT "'1' - Infinite Lives",IDC_STATIC,91,77,53,8
LTEXT "'2' - Stop Timer",IDC_STATIC,91,87,48,8
LTEXT "'3' - Open Exit",IDC_STATIC,91,97,44,8
LTEXT "'4' - Invulnerability",IDC_STATIC,91,107,56,8
LTEXT "'5' - Skip Level",IDC_STATIC,91,117,47,8
END


/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

pizza BITMAP DISCARDABLE "pizza.bmp"

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "Winupd.ico"
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////


Ive only shown the more important part for you...

100 DIALOG DISCARDABLE 0, 0, 236, 154 - ID 100, Dialog window, its discardable (i.e. can close :P), start at x,y coordinates 0,0 with
length 236 and Depth 154 pixels. Remember the depth is downwards unlike maths when the Y value
is upwards with positive values.

Dont worry about the Style section, unless you dont want a caption bar (title) then you can remove WS_CAPTION

CAPTION "Trainer v1.10" - change this to whatever you want the title to say
FONT 8, "MS Sans Serif" - Set font type and size, make sure you select a font everyone has


BEGIN
DEFPUSHBUTTON "Run Game",101,10,93,50,14 - Set a button with ID 101 (remember in asm file?) with co-ords 10,93 and length 50 and depth 14
DEFPUSHBUTTON "About!",102,178,93,50,14 - Set a button with ID 102, co-ords 178,93 and length 50 and depth 14
CONTROL 113,IDC_STATIC,"Static",SS_BITMAP | WS_BORDER,4,7,229,43 - Set the static area for a bitmap picture to be shown, and set border
GROUPBOX "Trainer Options :",IDC_STATIC,65,60,108,77 - Make a group box with title Trainer Options, at co-ords 65,60 etc etc
LTEXT "'1' - Infinite Lives",IDC_STATIC,91,77,53,8 |
LTEXT "'2' - Stop Timer",IDC_STATIC,91,87,48,8 |
LTEXT "'3' - Open Exit",IDC_STATIC,91,97,44,8 |- Set text to be shown at co-ords and length,depth
LTEXT "'4' - Invulnerability",IDC_STATIC,91,107,56,8 |
LTEXT "'5' - Skip Level",IDC_STATIC,91,117,47,8 |
END


Before I forget the CONTROL has an ID 113... These are important so the program can distinquish what is being used and refering to.


pizza BITMAP DISCARDABLE "pizza.bmp" - set the bitmap picture to be shown, best in 256 colors to keep size of trainer down.
Also take note of the size you set above, 229 length and 43 depth, make sure bitmap
file has those dimensions


IDI_ICON1 ICON DISCARDABLE "Winupd.ico" - Set the Icon of the trainer exe, make sure the icon is 256 colors again. There is lots
of icon editors on the net, that can convert from 16bit to 256.



Once you change what you need to change, save as Rsrc.rc (NOT anything else)...



Ok if everything is done correctly, you can run MAKEIT.BAT....


For best results, goto Start > Run > cmd {press enter} and in the dos window, type


cd/trainer/ (or whatever your folder name was)


then type


MAKEIT.BAT


This will help to show any errors without the window dissapearing.



If none, your trainer is complete, run it to test it :D


If it works and keys work etc...


While still in the dos window type



UPX -9 trainer.exe (or whatever your exe is called)


This will pack your file and encrypt it, to make it smaller and to stop noob thiefs stealing your work by changing text with a hex editor



Hope you understood all that


BYE

DABhand
26-08-2005, 16:58
Yeah you best read it from my txt on my webspace lol :P

paraidy
26-08-2005, 19:24
Always Great :D

caki
27-08-2005, 11:32
Very nice tut DABhand :)

Muji-FightR
28-08-2005, 13:12
Indeed very nice ;)
I dunno much about asm, i'd never be able to do something on my own :D
But it was a good introduction and really interesting (very well written, muy understandable)

TippeX
28-08-2005, 13:32
Here we are setting constant values, i.e. values that will never change at all. Whats EQU?


equ = equate

didnt_read_his_compiler_handbook_properly equ 1
dabhand equ didnt_read_his_compiler_handbook_properly
....

heheheh

DABhand
28-08-2005, 16:10
Here we are setting constant values, i.e. values that will never change at all. Whats EQU?


IDC_EDIT equ 3000


EQU evaluates the numeric value of 3000 and assigns the resulting constant value to IDC_EDIT.
EQU does not allow numeric equates to be redefined (i.e 3+4=7), you can however have 3+4 and it will
work out the value 7 for you.

If the value (3000) cannot be evaluated, EQU treats the value as text.





I did write more, as I said I didnt do this properly was a quick thing, quite hard to write out something and to try and make it easy :|

TippeX
28-08-2005, 16:30
you can also substitute 'equ' for =

;)

it works more to 'refine' the code and make it easier to understand
IDC_EDIT for example is the control code that the message handler gets sent when the user clicks the edit box or whatnot...

the code can either be...

cmp eax, IDC_EDIT

or

cmp eax, 3000

the latter being what the compiler actually translates it to

the concept is to make the code easier to read/understand without having to go back and check reference codes etc and to make changes to the code 'global' without you having to go through all the lines of the code and changing all the 3000's as/when you change the code that the edit box sends

DABhand
28-08-2005, 16:57
See now your making it complicated for the noobians to understand :P

lol

ask22
16-10-2007, 00:36
noobians to understand :P
lol

hi, i'm a newbie and i cant understand why there're so many errors:
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.

Assembling: D:\masm32\PROJECTS\TRNR.asm
D:\masm32\PROJECTS\TRNR.asm(142) : error A2111: conflicting parameter definition
: hWnd
D:\masm32\PROJECTS\TRNR.asm(142) : error A2111: conflicting parameter definition

D:\masm32\PROJECTS\TRNR.asm(148) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(148) : error A2114: INVOKE argument type mismatch :
argument : 1
D:\masm32\PROJECTS\TRNR.asm(150) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(150) : error A2114: INVOKE argument type mismatch :
argument : 1
D:\masm32\PROJECTS\TRNR.asm(252) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(252) : error A2114: INVOKE argument type mismatch :
argument : 1
D:\masm32\PROJECTS\TRNR.asm(261) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(261) : error A2114: INVOKE argument type mismatch :
argument : 1
D:\masm32\PROJECTS\TRNR.asm(265) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(265) : error A2114: INVOKE argument type mismatch :
argument : 1
D:\masm32\PROJECTS\TRNR.asm(145) : error A2006: undefined symbol : uMsg
D:\masm32\PROJECTS\TRNR.asm(147) : error A2006: undefined symbol : hWnd
D:\masm32\PROJECTS\TRNR.asm(153) : error A2006: undefined symbol : uMsg
D:\masm32\PROJECTS\TRNR.asm(156) : error A2006: undefined symbol : uMsg
D:\masm32\PROJECTS\TRNR.asm(158) : error A2006: undefined symbol : wParam
D:\masm32\PROJECTS\TRNR.asm(235) : error A2006: undefined symbol : uMsg
D:\masm32\PROJECTS\TRNR.asm(237) : error A2006: undefined symbol : wParam
D:\masm32\PROJECTS\TRNR.asm(238) : error A2006: undefined symbol : lParam
D:\masm32\PROJECTS\TRNR.asm(241) : error A2006: undefined symbol : wParam
_
Assembly Error
Для продолжения нажмите любую клавишу . . .

any help please?

TippeX
16-10-2007, 03:04
im guessing you didnt include windows.inc?

Synaesthesia
16-10-2007, 03:38
Funny how people take everything, shove it into a compiler and expect it to compile successfully :)

TippeX
16-10-2007, 03:44
well not everyone sets up their build enviroments well....

and the masm used there is well out of date... mines 7.10.6030...

@ask22 - i suggest you get an updated version of masm32, and setup your build enviroment properly...

DABhand
16-10-2007, 09:56
Hi yes sounds like you didnt include a .inc file. Most likely windows.inc.

Also I edited the first post, to show the correct URL for the txt form of the tutorial, which is easier to read and free of smilies :P

ask22
22-10-2007, 04:51
2: TippeX, Synaesthesia, DABhand

do this part of code show that i forget to include windows.inc???

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib\masm32\lib\user32.lib
includelib\masm32\lib\kernel32.lib

TippeX
22-10-2007, 05:24
nope it doesnt, so seeing as you're being so sarcastic, why not try and fix the issue yourself... it could be an old masm... but with responses like that, dont expect much help...

DABhand
22-10-2007, 09:49
Perhaps he doesnt realise even if its listed in his coding perhaps the file is missing!

jings crivens help ma boab.

As TippeX mentioned not a good attitude at all.

ask22
25-10-2007, 17:42
year, right, im a little sarcastic,
perhaps the file is missing! definetly,
with of without your help, people, i still tryin :mad: to make it...
also, as u still didn't noticed, there is NO source code (http://www.vwaskar.pwp.blueyonder.co.uk/asm/trainerasm.rar - not available), and no more Rsrc.rc file available to study.

Joe Forster/STA
26-10-2007, 04:14
If you're sarcastic then don't expect help from the very people you're being sarcastic at. Also, perhaps, you should realize that a file made online on the Web two years (!) ago might not be there anymore. (Heh, I remove my own no-CD patches from my own site within weeks even if I didn't submit them to GCW yet...) I suggest you read forum rule #7 before continuing with your sarcasm...

DABhand
26-10-2007, 09:48
year, right, im a little sarcastic,
definetly,
with of without your help, people, i still tryin :mad: to make it...
also, as u still didn't noticed, there is NO source code (http://www.vwaskar.pwp.blueyonder.co.uk/asm4FF/trainerasm.rar - not available), and no more Rsrc.rc file available to study.


Since its my webspace your getting from and I wrote the damn guide less being an arsehole would help.

http://www.vwaskar.pwp.blueyonder.co.uk/asm4FF/trainerasm.rar

I forgot to rename the link after MP hack sites were linking to my tuts, and I hate MP hacking.

pikachu5501
26-10-2007, 20:28
Nice tutorial. It is also a nice intro about asm coding and understanding ams for thoses how wants to debug stuff as well. As for me, i do my trainer in C++ (free borland builder mostly but sometime mingw but never vc) because it is for me easier to debug it and the size, with the bitmap is fairly around 70k. In dos though, ASM was a must on a 386/486 if someone wanted to do some cool and fast sidescrooling Intro with the music and all for the trainer.

Anyway, good stuff and all this for free!! :)

br0wn
05-11-2007, 14:05
Great, I've been looking for something like this for awhile.

Now, my problem is when I try to add a value (money/gold). Can this be done without any complicated changes? I have the addresses located with no problem for the game.

Is it possible to add values with how this is setup?

Thanks!

DABhand
05-11-2007, 15:07
Yeah dont see why not, one way would be to use ReadProcessMemory when you know the location, and then add whatever value to it like a simple equation like eax = eax + whatevervalue, then use WriteProcessMemory to put it back.

Or

Set aside some code cave which works out money values but have some space inside the code cave with nops.

And in the trainer when you press a key, have it add an add opcode

like add eax, ff

to add 255 to the amount.

When done it reverts to nops again

so each time you press the desired key it will add 255.


Also search for other trainer skeletons on the net, there may be some thats a bit easier for you to play about with, with the way you want it.

bleep
25-11-2007, 18:54
Can you give an example on how to play a wav after a key is pressed.

[edit] Never mind, I found what I needed;


; ------------------------------------------------------
; Includes
include \masm32\include\winmm.inc

includelib\masm32\lib\winmm.lib

; ------------------------------------------------------
; Data

Sound db "ding.wav",0

; ------------------------------------------------------
; Start

invoke PlaySound, ADDR sound, NULL, SND_FILENAME or SND_ASYNC

; ------------------------------------------------------

nuckfuts
28-11-2007, 11:39
If you're not sending unicode or a wide string in "Sound" variable, call PlaySoundA explicitly. It's more reliable as code, even if your compiler does convert it to it anyways. ;)

bleep
30-11-2007, 08:53
I'm sure that'll make more sense after I learn the language.. ;)

Sidz
04-09-2008, 06:19
Great tutorial as i am learning ASM now (and I like it :)
Thanks DABhand for this tutorial, but i have a question:

What if a game use a .dll instead of an .exe?
So you execute the .EXE to run the game (shows a video) and the .EXE loads the .dll with all the code to start the game

How can you solve this?

I hope you can help me in the right direction!

DABhand
04-09-2008, 06:31
Thats when you look into code shifting.

http://www.memoryhacking.com/Misc/Tut/About%20Pointers.htm

And a little tut on teleporting which uses pointers is on this thread

http://fileforums.com/showthread.php?t=81279


So in essence if you can find out where the specific dll is loaded into the memory and you know the offset of an address inside the dll (the offset will always be the same but the memory location will change) then its not that difficult to write something that will manipulate that offset.

TippeX
04-09-2008, 10:06
quite simple really.. hook LoadLibrary -> you'll get the base address from that...
or inside the injection code do a GetModuleHandle("filename.dll") sort of thing and you'll get the same thing... and as dab says all that changes really is the base address, the offset to patch will be (base+offset)... hardly rocket science.. just requires a slightly different approach

Sidz
04-09-2008, 18:16
Edit: Nevermind, got a bit confused last night...

TippeX
05-09-2008, 01:15
how can the game close the exe after loading the dll?
the dll can't run by itself unless its launched by rundll32....

perhaps the game is relaunching itself? in which case you'd need to hook its CreateProcess / ShellExecute etc...

it sounds quite strange though....

if the process exits, obviously hProcess is useless... hook exitprocess maybe, see whats going on...

Joe Forster/STA
05-09-2008, 04:21
I'm not an expert but I once saw something like CoExecute or something in the Windows API. So, yes, you can launch an external program and then exit. (This is supposing that the EXE is only a loader and the DLL is the main program.)

TippeX
05-09-2008, 04:33
yeh, but its quite strange... usually the exe would be the main process and to load a dll as another process you'd need to use something like rundll32 or maybe coexecute (couldn't find that in the api.. but im 1/2 asleep...) because by their design dll's aren't really the same as exe's..

Joe Forster/STA
05-09-2008, 06:45
I think I saw this CoExecute thingy in the launcher of recent Star Wars games. (It may only work for EXE's but, if you can additionally specify an entry procedure, DLL's might also work.)

TippeX
05-09-2008, 12:25
u sure you aren't thinking of cocreate ?

Joe Forster/STA
05-09-2008, 13:27
Don't remember... I searched for half an hour but haven't found the game I saw this in...

Sidz
05-09-2008, 16:14
Well here is the test game i use and i hope one of you can look at this and give the tutorial in ASM.


[mod notes]

user posted a link on rapidshare containing a game and a crack, and then wanted assistance in making some trainer code...
bad bad bad bad idea (especially in the mood i am in at the moment)...

DABhand
05-09-2008, 20:37
oh dear oh dear

Go read the forum rules especially no 1, and wonder why you got a telling off and the link removed.

PSYCH0!
08-09-2008, 10:47
What a shame this topic was so abruptly ended. Even when you provide a popup message about reading the forum rules, people still don't bother to read them.

The guy could have been wrong about the launcher terminating, or the .dll could have been an .exe file with the .dll file extension.

Or maybe CreateFileMapping() was used by the launcher. Diablo & the Hellfire expansion used it to create an object of itself, execute the object, and then terminate. It was an anti-debugging method where the programmer couldn't debug the current process -the debugger would terminate with the 1st .exe file.
(Of course, all that was a waste of time because all you had to do to stop it was to circumvent the example code that is shown in the Windows SDK function reference for the CreateFileMapping() function.)