CEAA教程:A Very In Depth Tutorial on Auto Assembler(四)

------------------------------ 
Bonus. Writing a Script 
------------------------------ 
    
既然你读了教程,那也应该很了解了,但你还是想知道更多。 我明白, 就如同我体会过的—遗憾。我不认为有任何关于写脚本的教程是我用的上的。 

  Code:  
  [ENABLE] 
  alloc(AutoAssembler,1024) 
  alloc(SayWhat,1024) 
  alloc(WooHoo,1024) 
  label(Continue) 
  registersymbol(WooHoo) 
  
  AutoAssembler: 
  mov eax,02 
  cmp eax,03 
  jne Continue 
  je SayWhat 
  
  Continue: 
  cmp eax,[WooHoo] 
  
  SayWhat: 
  jmp 0 
  [DISABLE] 
  dealloc(AutoAssembler) 
  dealloc(SayWhat) 
  dealloc(WooHoo) 
  unregistersymbol(WooHoo) 
  

还记得之前的这个脚本吗? 现在让我们用我们所学的大量内容把它弄完整。

  Code:
  [ENABLE] 
  alloc(AutoAssembler,1024) 
  alloc(SayWhat,1024) 
  alloc(WooHoo,1024) 
  label(Continue) 
  registersymbol(WooHoo) 
  
  AutoAssembler: 
  mov eax,02 
  cmp eax,03 
  jne Continue 
  je SayWhat 
  
  Continue: 
  cmp eax,[WooHoo] 
  
  SayWhat: 
  jmp 0 
  
  [DISABLE] 
  dealloc(AutoAssembler) 
  dealloc(SayWhat) 
  dealloc(WooHoo) 
  unregistersymbol(WooHoo) 
  

对于脚本你需要有些东西, 一个你试图hack的程序的真实内存的地址。 无论如何, 它都不能是一个随机的地址, 或者是一些你不希望它发生但是会导致其发生的地址(崩溃,也许)。这个地址对于这件事很重要。
但是为什么我们需要一个地址? 就如同之前我所说的,alloc 函数在你的程序中分配一块未使用内存。因为这是未使用的,程序不会访问这里,所以,你要让程序访问它。 
当你干预这些地址时,你需要注意一些至关重要的事情。第一, 你必须用与源码相同总量的字节。 如何知道一个操作码字节的数量呢? 简单,看在地址和操作码中间,那儿应该有一堆两个一组两个一组的字符,他们被称为Array of Bytes。
  
nop 函数对于这种情况非常有帮助。就如同我之前解释的那样,它的含义是“无操作”。并且它只用一个字节。这意味着,如果你用不了所有的字节位置,那你就可以用nop把它填满。 
当填字节时你可能会遇到三种情况。我已经描述了第一种你的代码比源码少的情况。剩下两种情况的一个是,你的代码所占的字节数和源码字节数相等,一切刚刚好。
但最后一种情况有些令人困惑,那就是你的代码的字节比源码的多。现在,你的代码的字节会把下面的代码字节覆盖,直到字节的位置够用。

为什么我们不玩Minesweeper呢? 一段时间之前,我还在学习写脚本的时候,我写了一小段代码(我还是我,但那时我还知道的很少)。

  Code:  
  [enable] 
  alloc(WhatNowMinesweeper,256)   //分配... 
  alloc(ChiliDog,4) 
  label(ReturnHere)  
  registersymbol(ChiliDog)               //注册... 
  
  ChiliDog: 
  dd 0                                         //用于参考引用,表示ChiliDog的值是从0开始
  
  01002FF5:                                 //这个地址是为MineSweeper写入时间的 
  jmp WhatNowMinesweeper            //我重写了操作码,让它跳转到我的脚本  
  nop                                          //填充了最后的字节 
  ReturnHere:                               //这个是干什么的我待会告诉你 
  
  WhatNowMinesweeper:                //我的实际代码 
  push eax                                   //保存eax, 我们不这么做就会有问题 
  mov eax,[ChiliDog]                      //把ChiliDog的值传入eax 
  mov [0100579C],eax                   //把存有ChiliDog值的eax存入时间
  pop eax                                    //让eax出栈,因为我们已经用完了
  jmp ReturnHere                          //跳转到ReturnHere, 待会解释
  
  [disable] 
  dealloc(WhatNowMinesweeper)     //取消分配内存
  dealloc(ChiliDog) 
  unregistersymbol(ChiliDog)           //反注册标识 
  
  01002FF5:                                //这是我修改来跳入我的代码的地址 
  inc [0100579C]                          //这是源操作码用以防止崩溃 
  

现在,最最先要做的。我要告诉你"ReturnHere"是什么。 如你所知,一个被告知要执行一个操作码的程序进程,他们会自动移动到下一个操作码,然后继续。 这就如同一个无限的轮回。这样,如果我们弄了条死路,即代码之后已经没有代码了,那这个程序几乎就会崩溃。因此, 我们要让它执行过我们的代码之后再返回到调用跳转之后的位置上,这样代码就可以继续了—并且我们也不会崩溃! =D 
关于写脚本还有很多内容。 请自由的提问并且评论你是否喜欢。 =)

你可能感兴趣的:(CEAA教程:A Very In Depth Tutorial on Auto Assembler(四))