发新话题
打印

[转载]在C中嵌入机器码的一种方式

[转载]在C中嵌入机器码的一种方式

信息来源:开放实验室 (openlab.nwpu.edu.cn) 【Visual C++】专栏

以下程序用VC6.0 CL编译器编译
编译参数 :  cl test.c /link kernel32.lib

程序在Win95下测试通过,运行结果:打开一个资源管理器
简要说明:
机器码在程序函数test中buffer里
在test中通过
push addr buffer  ; push ebp-80
ret 0
跳入机器码

这段代码如下工作
复制内容到剪贴板
代码:
push addr string1 ; string1 : "shell32.dll"
call   LoadLibrary

invoke ShellExecute  NULL,addr string2,0,0,0,5  ;  string2 : "open"  打开资源管理器

push addr ExitProcess
ret 0                      ;结束进程

#include<stdio.h>
#include<windows.h>
int test()
{
// Follow Addr Tested on Windows95
//LoadLibrary   Addr: 0BFF775F3h
//GetProcAddress Addr: 0BFF76DD8h
//ShellExecute  Addr: 07FDE9211h
//ExitProcess   Addr: 0bff8b191h

     char buffer[80]=
     {

           0xEB,0x1E,                   //jmp      @call
           0x5D,                        //pop  ebp               @jm
           0x55,                        //push      ebp
           0xFF,0x55,0x11,                   //call      dword ptr [ebp+11h]
           0x6A,0x05,                   //push      5
           0x6A,0x00,                   //push      0
           0x6A,0x00,                   //push      0
           0x6A,0x00,                   //push      0
           0x8B,0xC5,                   //mov      eax,ebp
           0x83,0xC0,0x0C,                   //add      eax,0Ch
           0x50,                        //push      eax
           0x6A,0x00,                   //push      0
           0xFF,0x55,0x15,                   //call      dword ptr [ebp+15h]
           0x68,0x91,0xB1,0xF8,0xBF,               //push      0BFF8B191h  ExitProcess  地址
           0xC3,                        //ret
           0xE8,0xDD,0xFF,0xFF,0xFF,                    //call      @jm          @call
           &#39;s&#39;,&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;3&#39;,&#39;2&#39;,&#39;.&#39;,&#39;d&#39;,&#39;l&#39;,&#39;l&#39;,0,
                       &#39;o&#39;,&#39;p&#39;,&#39;e&#39;,&#39;n&#39;,0,
           0xf3,0x75,0xf7,0xbf,        //LoadLibrary  地址
           0x11,0x92,0xde,0x7f         //ShellExecute  地址
     };
     _asm
     {
          pop     edi
          pop     esi
          pop     ebx
         
          sub ebp,80
          push ebp
          ret 0

     }
}
void main()
{
     

     HINSTANCE hw = LoadLibrary("user32.dll");
//     FARPROC fp = GetProcAddress(hw,"ShellExecute");
//     ShellExecute(0,"open",0,0,0,5);
//     printf("ShellExecute addr :%p",ShellExecute);
/*     printf("LoadLibrary Addr :%p\n",LoadLibrary);
     fp = GetProcAddress(hw,"GetProcAddress");
     printf("GetProcAddress Addr: %p\n",fp);
     printf("GetProcAddress Addr: %p\n",GetProcAddress);
*/
     printf("%i\n",test());

}
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

test() 正确返回代码已经被我截获
test()
{
}
对应为:
;test()
;{
    push ebp      
    mov ebp,esp  ; 现在ebp+4  处为test返回地址
    sub  esp,80    ;为buffer[80]留空间        过ebp-80处为buffer[0]地址

    . . . . . . .


   ;  test()准备返回
   add esp,80   ;修正esp    dword ptr [ esp] 为 保存的ebp值   dword ptr[esp+4] 为 test返回地址
   pop ebp      ;现在栈顶为test返回值   
   ret 0         ;返回调用test的main函数中
  
;}


_asm
{
}
对应汇编为
;_asm
;{
   push ebx
   push esi
   push edi


   . . . .
  
   pop edi
   pop esi
   pop ebx
  
;}

现在是
test()
{
   char buffer[80];
   _asm
  {
      pop edi    ;抵消 _asm进入时加入的三个push
      pop esi
      pop ebx
      
      sub ebp,80  ;ebp现在为buffer入口
      push ebp    ;现在栈顶为buffer入口地址  下条ret 将以此地址作为返回地址,进入buffer
      ret 0        ;进入buffer ,注意ret 之后esp+80也是buffer尾部  esp+84是ebp  esp+88是test
                  ;正确返回地址
  }
}
在buffer中的代码有如下  这部分相当是test()函数最后准备返回时的代码,参加上面test()

add  esp,80  ;现在栈顶是ebp  
pop  ebp      ;现在栈顶是test返回地址
ret   0        ;正确返回  好了又回到了main()

还有win32中是32位已经是在同一个线性空间cs;ss;ds等已经失去dos下ss:sp  cs:ip
等功能,而是直接在空间中以eip, esp等来寻址  当然用能到堆栈中执行

真正有难度的东东是机器嘛那一段,想想里面有需要的string,而且还要string的地址
解觉办法是依赖jmp  和call  ,他们都是用相对当前地址跳转,尤其是call 会保存下一条指令地址
我们把string放在call的下面call调用后就会在栈顶压入string的地址  ^_*

那段机器码如下
  jmp  sh_call    ;在sh_call处是 call sh_jm   有回来了!!  但此时已压入了string的地址

sh_jm:
  
  pop  ebp      ; ebp中为string的地址

  . . . . . . .

sh_call:

  call  sh_jm
  string db  . . . .


编译参数没什么意义就是让程序能编译通过

附cl产生的汇编程序
都可以在  ftp://202.117.82.4/asm/asm-c/下找到

; Listing generated by Microsoft (R) Optimizing Compiler Version 13.00.8905

    TITLE    shellcode2.c
    .386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT    SEGMENT PARA USE32 PUBLIC &#39;CODE&#39;
_TEXT    ENDS
_DATA    SEGMENT DWORD USE32 PUBLIC &#39;DATA&#39;
_DATA    ENDS
CONST    SEGMENT DWORD USE32 PUBLIC &#39;CONST&#39;
CONST    ENDS
_BSS    SEGMENT DWORD USE32 PUBLIC &#39;BSS&#39;
_BSS    ENDS
$$SYMBOLS    SEGMENT BYTE USE32 &#39;DEBSYM&#39;
$$SYMBOLS    ENDS
_TLS    SEGMENT DWORD USE32 PUBLIC &#39;TLS&#39;
_TLS    ENDS
FLAT    GROUP _DATA, CONST, _BSS
    ASSUME    CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

PUBLIC    _test
; Function compile flags: /Odt
_TEXT    SEGMENT
_buffer$ = -80
_test    PROC NEAR
; File c:\work\asm-c\shellcode2.c
; Line 4
    push    ebp
    mov    ebp, esp
    sub    esp, 80                    ; 00000050H
    push    ebx
    push    esi
    push    edi
; Line 14
    mov    BYTE PTR _buffer$[ebp], -21        ; ffffffebH
    mov    BYTE PTR _buffer$[ebp+1], 36        ; 00000024H
; Line 15
    mov    BYTE PTR _buffer$[ebp+2], 93        ; 0000005dH
; Line 16
    mov    BYTE PTR _buffer$[ebp+3], 104        ; 00000068H
    mov    BYTE PTR _buffer$[ebp+4], -57        ; ffffffc7H
    mov    BYTE PTR _buffer$[ebp+5], -3        ; fffffffdH
    mov    BYTE PTR _buffer$[ebp+6], 99        ; 00000063H
    mov    BYTE PTR _buffer$[ebp+7], 0
; Line 17
    mov    BYTE PTR _buffer$[ebp+8], -1
    mov    BYTE PTR _buffer$[ebp+9], 85        ; 00000055H
    mov    BYTE PTR _buffer$[ebp+10], 17        ; 00000011H
; Line 19
    mov    BYTE PTR _buffer$[ebp+11], -125        ; ffffff83H
    mov    BYTE PTR _buffer$[ebp+12], -8        ; fffffff8H
    mov    BYTE PTR _buffer$[ebp+13], 0
; Line 20
    mov    BYTE PTR _buffer$[ebp+14], 116        ; 00000074H
    mov    BYTE PTR _buffer$[ebp+15], 17        ; 00000011H
; Line 22
    mov    BYTE PTR _buffer$[ebp+16], 106        ; 0000006aH
    mov    BYTE PTR _buffer$[ebp+17], 5
; Line 23
    mov    BYTE PTR _buffer$[ebp+18], 106        ; 0000006aH
    mov    BYTE PTR _buffer$[ebp+19], 0
; Line 24
    mov    BYTE PTR _buffer$[ebp+20], 106        ; 0000006aH
    mov    BYTE PTR _buffer$[ebp+21], 0
; Line 25
    mov    BYTE PTR _buffer$[ebp+22], 106        ; 0000006aH
    mov    BYTE PTR _buffer$[ebp+23], 0
; Line 28
    mov    BYTE PTR _buffer$[ebp+24], -125        ; ffffff83H
    mov    BYTE PTR _buffer$[ebp+25], -59        ; ffffffc5H
    mov    BYTE PTR _buffer$[ebp+26], 12        ; 0000000cH
; Line 29
    mov    BYTE PTR _buffer$[ebp+27], 85        ; 00000055H
; Line 30
    mov    BYTE PTR _buffer$[ebp+28], 106        ; 0000006aH
    mov    BYTE PTR _buffer$[ebp+29], 0
; Line 32
    mov    BYTE PTR _buffer$[ebp+30], -1
    mov    BYTE PTR _buffer$[ebp+31], 85        ; 00000055H
    mov    BYTE PTR _buffer$[ebp+32], 9
; Line 34
    mov    BYTE PTR _buffer$[ebp+33], -125        ; ffffff83H
    mov    BYTE PTR _buffer$[ebp+34], -60        ; ffffffc4H
    mov    BYTE PTR _buffer$[ebp+35], 80        ; 00000050H
; Line 35
    mov    BYTE PTR _buffer$[ebp+36], 93        ; 0000005dH
; Line 36
    mov    BYTE PTR _buffer$[ebp+37], -61        ; ffffffc3H
; Line 37
    mov    BYTE PTR _buffer$[ebp+38], -24        ; ffffffe8H
    mov    BYTE PTR _buffer$[ebp+39], -41        ; ffffffd7H
    mov    BYTE PTR _buffer$[ebp+40], -1
    mov    BYTE PTR _buffer$[ebp+41], -1
    mov    BYTE PTR _buffer$[ebp+42], -1
; Line 38
    mov    BYTE PTR _buffer$[ebp+43], 115        ; 00000073H
    mov    BYTE PTR _buffer$[ebp+44], 104        ; 00000068H
    mov    BYTE PTR _buffer$[ebp+45], 101        ; 00000065H
    mov    BYTE PTR _buffer$[ebp+46], 108        ; 0000006cH
    mov    BYTE PTR _buffer$[ebp+47], 108        ; 0000006cH
    mov    BYTE PTR _buffer$[ebp+48], 51        ; 00000033H
    mov    BYTE PTR _buffer$[ebp+49], 50        ; 00000032H
    mov    BYTE PTR _buffer$[ebp+50], 46        ; 0000002eH
    mov    BYTE PTR _buffer$[ebp+51], 100        ; 00000064H
    mov    BYTE PTR _buffer$[ebp+52], 108        ; 0000006cH
    mov    BYTE PTR _buffer$[ebp+53], 108        ; 0000006cH
    mov    BYTE PTR _buffer$[ebp+54], 0
; Line 39
    mov    BYTE PTR _buffer$[ebp+55], 111        ; 0000006fH
    mov    BYTE PTR _buffer$[ebp+56], 112        ; 00000070H
    mov    BYTE PTR _buffer$[ebp+57], 101        ; 00000065H
    mov    BYTE PTR _buffer$[ebp+58], 110        ; 0000006eH
    mov    BYTE PTR _buffer$[ebp+59], 0
; Line 40
    mov    BYTE PTR _buffer$[ebp+60], -13        ; fffffff3H
    mov    BYTE PTR _buffer$[ebp+61], 117        ; 00000075H
    mov    BYTE PTR _buffer$[ebp+62], -9        ; fffffff7H
    mov    BYTE PTR _buffer$[ebp+63], -65        ; ffffffbfH
; Line 41
    mov    BYTE PTR _buffer$[ebp+64], 17        ; 00000011H
    mov    BYTE PTR _buffer$[ebp+65], -110        ; ffffff92H
    mov    BYTE PTR _buffer$[ebp+66], -34        ; ffffffdeH
; Line 42
    mov    BYTE PTR _buffer$[ebp+67], 127        ; 0000007fH
    xor    eax, eax
    mov    DWORD PTR _buffer$[ebp+68], eax
    mov    DWORD PTR _buffer$[ebp+72], eax
    mov    DWORD PTR _buffer$[ebp+76], eax
; Line 46
    pop    edi
; Line 47
    pop    esi
; Line 48
    pop    ebx
; Line 55
    sub    ebp, 80                    ; 00000050H
; Line 56
    push    ebp
; Line 57
    ret    0
; Line 60
    pop    edi
    pop    esi
    pop    ebx
    mov    esp, ebp
    pop    ebp
    ret    0
_test    ENDP
_TEXT    ENDS
PUBLIC    _main
EXTRN    _printf:NEAR
_DATA    SEGMENT
$SG53167 DB    &#39;%i&#39;, 0aH, 00H
; Function compile flags: /Odt
_DATA    ENDS
_TEXT    SEGMENT
_main    PROC NEAR
; Line 62
    push    ebp
    mov    ebp, esp
; Line 75
    call    _test
    push    eax
    push    OFFSET FLAT:$SG53167
    call    _printf
    add    esp, 8
; Line 77
    xor    eax, eax
    pop    ebp
    ret    0
_main    ENDP
_TEXT    ENDS
END
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

发新话题