- -----=========----- -------==========================================---------- ----------=====_masta_的 Win95 汇编教程 part 2 修正版 1=====----------- -------==========================================----------
( I called this revision 1 because it contains new sourcecode without errors _masta_ found when going through it again - fungus )
--==介绍==--
Hi, Part0 和 part1 相对比较成功,我也很高兴发表 part 2了。 实际上我很想做一些关于 GUI 的东西,可是最近我很忙,所以现在只能让你们 看到这些没有 GUI 代码的东西。不管怎样,这也是一个很有趣的东西。 从这篇教程开始我不再会解释一些诸如 MessageBox 之类简单的东东了, 这在头两篇都是解释的非常详细的。我想这也不会给你带来什么不便,如果你看过 头两篇的话。
--==我们需要什么?==--
1. 文本编辑器 2. TASM 5.0 和库文件等等。 3. Windows API 参考手册 (WIN32.HLP) 4. 星际争霸(StarCraft) (ONLY for testing purposes!;]) (Sendfree:MyGod,他要做什么?) 5. 一些脑细胞 ;) 6. 一些基本的汇编知识 (前面两课) 7. Numega Softice 3.xx (并不是必需的) (Sendfree: 这么暴力的工具也用!做什么?! 你的周围有没有Cracker 啊,向他们要一个。)
--==这次我们要做什么?==--
哪一个游戏迷不想有下面的这些东西呢?
more lives more money more energy more gas (sendfree: gas 是星际中的一种资源(就是钞票),下面的 mineral 也是) more ...
我说的就是游戏修改器(Trainer),这在C64-/Amiga-/PC-DOS-times 是非常常见的, 但是现在却越来越少了,真让人怀念那段美好的岁月。 所以这次拿星际开刀(当然我也知道已经有好些修改器了!
理由:-这个游戏眼下非常流行 -我是在玩这个游戏的时候得到写这篇教程的灵感 :)
--==LET'S GO==--
开始工作之前先仔细考虑一下。
游戏修改器的定义:-一个小程序,可以改变游戏的部分内存数据,例如 这样可以得到更多的 money ...
一般说来,在windows 中一个程序不能读写其他程序的内存空间。幸运的是 我们最亲爱的朋友 Billy 作了一些本来用于 debug 的函数,我们可以用这些 东东达到我们目的。
它们就是:OpenProcess, WriteProcessMemory 和 ReadProcessMemory. 通过这组函数我们就可以读写其他程序的内存空间。 最基本的,我们的程序就像一个除错器(debugger),存取其他程序的内存 并改变它。
--==结构==--
1. 介绍 (用 MessageBox 显示)
2. 得到要修改的程序的 Process_ID (找到 Starcraft 的主窗口; 然后再找到进程号)
3. 打开进程
4. 改变值
5. 关闭进程, 结束 (成功)
--==重要的 API 函数==--
我们可以用 FindWindowA 得到主窗口的句柄,然后得到窗口类的名字("SWarrClass")和 窗口的名字("Starcraft")。这些东西可以从 Softice (TASK->HWND)中获取。 (sendfree:没有用过 softice 的朋友可以一支雪糕贿赂Cracker 们,然后取点经。)
由窗口句柄(windowshandle)可以得到相应的进程,再用 GetWindowThreadProcessId得到 进程ID(PID).
现在我们可以通过 PID->OpenProcess 的帮助抓住进程内存空间的句柄。 现在一切都变得容易了,我们通过 WriteProcessMemory函数操作程序的句柄就像 通常的文件操作一样操作程序的内存。
最后也是很重要的,调用 CloseHandle 关闭进程的句柄。这在 Win95 中不是真的很重要的,但是谁会 相信一个来自 Redmont(sendfree:雷蒙得,MS的总部)的软件呢 ;-)?
最后一个函数就是 ExitProcess.
--==内存地址==--
我们能够很轻松的通过 debugger搜索显示在屏幕上的十进制数相应的十六进制数 来得到minerals 的地址,在我的系统里是这样的:
Minerals = 04EFE08h Gas = 04EFE38h
--==THE SOURCE==--
代码并不长,而且结构也不是很好,但是不管怎样,应该是很容易看懂的...
;This is a slightly edited source to my tutorial (Part 2) ;I did a mistake while searching the informations for the memory locations ;not taking care, that starcraft uses different locations ...
;Only change is that the million-value is written 2 times ;and 8 bytes instead of 4
; Set some params for the assembler .386P Locals jumps
.Model Flat ,StdCall PROCESS_VM_WRITE equ 020h ; Flags for the write-access PROCESS_VM_OPERATION equ 008h ; to the process
mb_ok equ 0 minerals_pos equ 04efe08h gas_pos equ 04efe38h
; declaration of used API-functions
extrn MessageBoxA : PROC ; Show a Messagebox extrn FindWindowA : PROC ; Find Window with the name extrn GetWindowThreadProcessId :Proc; Find PID with the HWND extrn OpenProcess : PROC ; Procedure to access the process extrn WriteProcessMemory: PROC ; Write into memory of the running ; program extrn CloseHandle : PROC ; Close the handle again ; Cleanup, after use ;) extrn ExitProcess : PROC ; Procedure to exit the program
; here begins our Data .Data
caption db "_masta_'s essay on Win32-ASM-Coding, part 2",0 ;Captionstring, 0-terminated
text db "Hi, here we are at part 2",13,10 db "This tut will describe you how to make",13,10 db "Win32-ASM Trainer",0
; Introtext , 0-terminated
err_cap db "ERROR",0 ; Caption for Errormessages
notrun db "Sorry, Starcraft is not running",0 ; Error if SC isn't running
no_write db "Mmmhhhh, a problem, by writing",13,10 db "to Starcrafts memory",13,10,0
readycap db "Ready",0 ; Caption for "ready"
readytxt db "Ok, now you have 1000000 Minerals and Gas",0
; Text for "ready"
million dd 1000000 ; How much do you want??? ;] dd 1000000
wnd_name db "Starcraft",0 ; Name of the Starcraft-window cls_name db "SWarClass",0 ; Class of the Starcraft-window
pid_sc dd ? ; Here we save the PID ...
p_hand dd ? ; and here the handle to the ; process
; And here we start with our code
.Code Main: push mb_ok push offset caption push offset text push 0 call MessageBoxA ;Startmessage
is_SC_RUN:
push offset wnd_name push offset cls_name call FindWindowA ; Find Window handle with Windowclass and ; -name
cmp eax,0 ; if 0, window is not existing jz SC_isnt_run_end; --> Starcraft is not launched
push offset pid_sc ; Where to save the PID ? push eax ; PUSH Windowhandle call GetWindowThreadProcessId ; Determine PID with Windowhandle
open_the_process: push pid_sc ; PUSH PID push 0 ; only used when ; building new ; processes push PROCESS_VM_WRITE OR PROCESS_VM_OPERATION ; activate write-access
call OpenProcess ; Get handle of Starcraft mov p_hand,eax ; Save handle to p_hand
change_Minerals:
push 0 ; Can be zero mostly push 8 ; Write 8 Bytes (2 Dwords) push offset million ; How much ? (1 Million) push minerals_pos ; 1st Memoryaddress push p_hand ; Handle to the process call WriteProcessMemory; write minerals cmp eax,0 jz error_on_write ; If any error while writing (eax=0) -> end
change_gas: ; the same again for gas, but this time ; the memory address of the gas is PUSHed push 0 push 8 push offset million push gas_pos push p_hand call WriteProcessMemory cmp eax,0 jz error_on_write
Trainer_ready:
push mb_ok push offset readycap push offset readytxt push 0 call MessageBoxA ; Everything OK
close_the_PID_Handle: push p_hand Call CloseHandle ; CloseHandle jmp end_ ; Go to End
error_on_write:
push mb_ok push offset err_cap push offset no_write push 0 call MessageBoxA ; Mmmhhh, Error while writing jmp close_the_PID_Handle ; Close handle before quit
SC_isnt_run_end:
push mb_ok push offset err_cap push offset notrun push 0 call MessageBoxA ; nothing there to train =( end_:
CALL ExitProcess ; Exit program End Main ; End of Code Determination of Jump-point (Main)
;--------------------------==END OF SOURCE==----------------------------
;--------------------------------START---------------------------make.bat @echo off echo assembling your trainer tasm32 /mx /m3 /z /q w95asm_2 tlink32 -x /Tpe /aa /c w95asm_2,w95asm_2,, import32.lib del *.obj del *.map ;---------------------------------END----------------------------make.bat
--==FINAL WORDS==--
OK, as I told you before this was a little tutorial, but I think very interesting anyway. I guess there is not much to optimize (sorry fungus), maybe the routine for writing into memory (use of a procedure). I hope my mailbox ([email protected]) is flodded soon (CRITICS ARE WELCOME) and you are all here next time. I promise the next one will be about GUI, because many people told me to do so. BTW, I am trying to build an IRC channel (EFNET) on this (#win32asm) and finally there is a project-page 'HTTP://win32asm.cjb.net'! If anyone is interested, any contribution to this subject is very welcome, we are waiting for it ... I really hope there are enough people, who spend their time on this subject and who are willing to give their knowledge to others, too.
--==WISE WORDS==--
------===========================================================------- -----=====A hardcoded serial is as common as a 25-year-old virgin=====------ ------===========================================================------- -----=========----- -

|