_masta_的 Win95 汇编教程 part 2

类别:编程语言 点击:0 评论:0 推荐:

                          -         
          -----=========-----
           -------==========================================----------
----------=====_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=====------
  ------===========================================================-------
                          -----=========-----
       -


 

本文地址:http://com.8s8s.com/it/it30279.htm