Delphi写ShellCode获取Kernel32.DLL的地址.

好几年前曾写过一些ShellCode代码.
Delphi是最适合写ShellCode的工具
很多年没用了,今天刚刚回头看了一下,发现是随着系统的发展,其中获取Kernel32.DLL的方法在Vista/WIN7时代和X64中都已经不使用了.
就完善了一下.
现在是XP/Vista/WIN7以及X86/X64通吃.

function Kernel32Handle(): HMODULE;
{$IFDEF CPUX64}
asm
  mov rbx,$60
  mov rax,[gs:rbx]   // peb
  mov rax,[rax+$18]  // LDR
  mov rax,[rax+$30]  // InLoadOrderModuleList.Blink,
  mov rax,[rax]  // [_LDR_MODULE.InLoadOrderModuleList].Blink kernelbase.dll
  mov rax,[rax]  // [_LDR_MODULE.InLoadOrderModuleList].Blink kernel32.dll
  mov rax,[rax+$10]  //[_LDR_MODULE.InLoadOrderModuleList]. BaseAddress
end;
{$ELSE}
asm
  mov     eax,[fs:$30]  // Peb
  mov     eax,[eax+$C]  // LDR
  mov     eax,[eax+$C]  // InLoadOrderModuleList
  mov     eax,[eax]   // [_LDR_MODULE.InLoadOrderModuleList].Blink kernelbase.dll
  mov     eax,[eax]    //[_LDR_MODULE.InLoadOrderModuleList].Blink kernel32.dll
  mov     eax,[eax+$18] //[_LDR_MODULE.InLoadOrderModuleList]. BaseAddress
end;
{$ENDIF}

另一方面之前写过一个FixChar是修正Delphi的的字符串常量在ShellCode中的相对位置的.具体就是Delphi的编译器特点,字符串常量不是象微软编译器那样在只读数据段,而是附在函数尾部.因为ShellCode运行位置不固定,所以只要修正偏移即可.这点比用C写ShellCode不能使用字符串常量而要事先计算出Hash值方便多了.
本来也想改成支持X64的.却发现有惊喜.
FixPChar(‘abcdefg’);
实际上在编译的时候变成了如下截图的样子.

不再是把字符串常量地址直接拿来用,而是用的相对地址.也就是说实际上X64的ShellCode,Delphi连字符串常量的地址都不用修正了,因为它用的是相对地址.
新的FixChar如下:

Function FixPChar(Value: PChar): PChar;
{$IFDEF CPUX64}
asm
  mov rax,rcx //Delphi X64字符串常量用的相对地址算出来的(X64中绝对地址比较少,一般都有32位数的相对地址偏移.例如跳转,造成Hook的时候要用一些技巧),这个函数纯属做样子,是为了统一32位代码
end;
{$ELSE}
asm
  call   @next                //
@next:    pop    ecx                  // ecx里面装的就是@next的相对地址,当前执行时
  mov    ebx, offset @next    // ebx里面装的就是@next的绝对地址,编译时生成的
  add    eax, ecx             // 返回Value的地址+(相对地址-绝对地址)
  sub    eax, ebx
end;
{$ENDIF}

写上面的这些代码的时候对比用VC来写,又一次感叹Delphi做ShellCode太方便了,VC在X64中是不能内嵌汇编的,必须蛋疼的单独再写一个asm文件,再把这个asm编译成obj链接进来.

此条目发表在Delphi, 未分类分类目录。将固定链接加入收藏夹。

Delphi写ShellCode获取Kernel32.DLL的地址.》有 2 条评论

  1. 匿名说:

    x64下的shellcode没必要这样重定位,直接计算就可以了
    反正都是lea 取rel+xxx这样的偏移地址的
    代码还能优化
    mov eax,[fs:$30]
    替换成:
    cdq
    mov eax, [fs:edx+$30]
    就少两个字节

  2. 匿名说:

    其实delphi最大的好处也不是代码优化-代码优化不是很好。
    适合写shellcode的一个最大的原因是。编译器产生的代码是固定的不会改变
    void Start(){}
    void Entry(){}
    void End(){}
    xx = &End – &Start;
    这样计算的时候如果由于End不经常用根据数据约束,Start会被优化到距离Entry近的位置。简单的一句话。这个代码会被改变。有可能Entry根本不会再Start-End之间的内存区域。发生这样的变动是很痛苦的.而且C\C++在64位下已经不能内嵌汇编和直接使用汇编了。delphi依然坚挺。种种问题算下来其实delphi很好,当然C++ Builder也挺好.

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

你必须启用JavaScript