Arm壳的 StolenCode ,很有规律,想试手编程,OD的纯脚本运行会慢得很惊人,至少在我的慢机很常见

我的 Dll Delphi源码 还没完成的。。。,只做了一部分,小测试过一下,不是很好


贴上来: 

先附用 OllyMachines 记录数据的脚本
// 一个字,“乱”
// Arm 的StolenCode 记录数据脚本
__asm
{
pushfd
pushad
push 40
push 1000
push 20000
push 0
call KERNEL32.VirtualAlloc
}

cmp eax, 0
je verr
mov reg11, eax   // dwOpLenTab 的值
mov reg15, eax
invoke logtext, "★★★★★ 成功申请下面的空间地址:"
invoke loglong, reg11
invoke GotoDumpAddr, reg11

__asm
{
popad
popfd
}

add reg15, 0x10000   // 划分一个空间给 记录 dwLogAddressTab 值的表
mov reg10, 0x587000  // StolenCode 节首地址 dwStolenCodeSection 的值
mov reg00, reg10

mov reg12, 0
mov reg13, 0
mov reg14, reg11
invoke GotoDumpAddr, reg11

loop:
cmp reg10, 0x596FC2  // 此处是比较 StolenCode 块的结束地址
je end

mov reg16, reg10
invoke ReadMemLong, reg16, 1
cmp reg00, 0xE9
jne skip
inc reg16
invoke ReadMemLong, reg16, 4
cmp reg00, 0
je skip
dec reg16
mov reg18, reg00
invoke WriteMemLong, reg15, reg16, 4
add reg15, 4
add reg16, 5
add reg16, reg18  // 取得返回地址

checking:
invoke GetPrevOpAddr, reg16, 1  // 逆向扫描返回地址
mov reg16, reg00
invoke ReadMemLong, reg16, 1
cmp reg00, 0xE9
jne checking                    // 直到找到JMP指令
invoke WriteMemLong, reg15, reg16, 4
add reg15, 4

skip:
invoke GetNextOpAddr, reg10, 1
mov reg12, reg00
sub reg12, reg10
mov reg10, reg00
invoke WriteMemLong, reg11, reg12, 1
inc reg11
inc reg13
jmp loop

end:
invoke LogText, "☆☆☆☆☆记录指令数量为:"
invoke LogLong, reg13 
invoke DumpMem, reg14, 0x20000, "OpLen_Tab.bin"
invoke msg, "Well Done!"
halt

verr:
__asm
{
popad
popfd
}
invoke msg, "发生一个申请内存的错误!"
halt





///////////////////////////////////////////////////////

library RestoreStolen;

uses
  SysUtils,
  Windows,
  Classes;
  
{$R *.RES}
// 小弟感觉这是自己真正的编程的头一次开始,所以写得很烂...
// 变量定义得比较奢侈,牛哥们可以指点指点..., 有值得优化的地方指点指点
// Nop 垃圾指令还在测试中,所以还缺一个移动还原动作的代码。。。
Type
  Tpackvar = record
      PatchAddr    :^Dword; // 这个正式还原时用,暂未用
      LenTab       :Dword;  // 指令长度表起始地址
      Sbegin       :Dword;  // 一个小的 StolenCode 块的起始地址
      Send         :Dword;  // 一个小的 StolenCode 块的结束地址
      pNextAddr    :^Dword; // 指向第 n 个块表的指针
      count        :Dword;  // 作临时计算地址过渡用
      len          :Byte;   // 保存取指令长度表一个索引指向的size
      abyte        :Byte;   // 临时用的字节保存变量
      aword        :Word;   // 作用同上(字),可能会用上
      adword       :Dword;  // 作用同上(双字),可能会用上
      pLen         :^Byte;  // 全局用的指令长度表指针变量
      pbyte        :^Byte;  // 单个 StolenCode 块的指针变量
      tbyte        :^Byte; // pbyte 某位置的临时保存
      cbyte        :^Byte; // pbyte 某位置的临时保存
      pword        :^Word; // 作保存,需要时取用
      tword        :^Word; // 作用同上
      cword        :^Word;
      pdword       :^Dword; // 作保存,需要时取用
      tdword       :^Dword; // 作用同上
      cdword       :^Dword;
      temp         :Pointer; // 保存指针变量,作取用
      i            : integer; // 这个没有用上,以后不知是否会用
  end;

procedure Checkdust2(myvar: Tpackvar);// 2字节的公用调用检测是否配对 的过程
begin
  myvar.tword  :=  Pointer(myvar.pLen) ; //取当前指令长度表指针
  myvar.tbyte  :=  Pointer(myvar.pLen) ;
  myvar.cword  :=  myvar.temp ;

  While Dword( myvar.cword ) <  myvar.Send  do
    begin
      inc (myvar.tbyte );
      myvar.abyte  :=  myvar.tbyte^ ;
      myvar.count  :=  Dword( myvar.cword ) + myvar.abyte  ;
      myvar.cword  :=  Pointer( myvar.count );
      if ( myvar.abyte =2 ) and ( myvar.pword^ = myvar.cword^ )then
        begin
          myvar.pword^  := $9090 ;
          myvar.cword^  := $9090 ;
          break;
        end;
    end;
end;

Function RestoreStolenCode( dwOpLenTab, dwLogAddressTab, dwStolenCodeSection: Dword ) : boolean ; stdcall ;
var
handle: Thandle;
myvar : Tpackvar;
flag  : boolean;

begin
flag   := f