代码改变世界

【老马识途】自己写二进制代码并执行

2014-03-18 00:58  撞破南墙  阅读(1654)  评论(0编辑  收藏  举报

1.1  自己构建二进制代码并跳转执行

该段代码实现的功能是对某个变量赋值。

思路:

自己分配一片内存在其中写入机器码。Jmp过去执行,执行完再jmp回来。

定位用 “标签:” 的方式

1.1.1  赋值

  

猜测 C7 45 表示 mov 

F8 指向 ebp-8的位置

EC 指向 ebp-14 

7B 00 00 00 表示123 

再看一段代码

  

突然想到我要赋值的是全局变量,而以上是局部变量的做法。

    34:  gi=1;

002E355E C7 05 00 70 2E 00 01 00 00 00 mov         dword ptr ds:[002E7000h],1      

Mov 是  C7 05

Gi 的 地址 00 70 2E 00

立即数 01 00 00 00 

所以格式为

Mov

Gi

2

C7 05

&gi

02 00 00 00

2

4

4

 

1.1.2  跳转jmp 

    24:  goto label2;

00192D4C EB 0B                jmp         00192D59  

00192D4E EB 09                jmp         00192D59  

    25:  goto label1;

00192D50 EB 26                jmp         00192D78

00192D4C + 0B +2=00192D59  

00192D4E+ 09 +2= 00192D59  

猜测 EB 是 jmp (百度后知道是 近跳转 )

偏移的地址=当前地址-目标地址-2  相对偏移位置不好弄

直接跳转的是 FF 25 

 

JMP

ADDRESS

FF 25

 

2

4

 

内存的模样

总长16char

C7 05

&gi4

02 00 00 00

FF 25

ADDRESS4

 

自己写的内存共16

c7 05 00 70 41 00 02 00 00 00 

ff 25 08 16 41 00 

跳转到该段内存开始执行的样子

001856F0 C7 05 00 70 41 00 02 00 00 00 mov         dword ptr ds:[417000h],2  

001856FA FF 25 08 16 41 00    jmp         dword ptr ds:[411608h]  

其中 0x00411608  8b f4 确实是正确的位置

但是为什么跳转的位置不对

 

查清之后发现 

jmp(ff 25) 这个指令 紧跟的 应该是目标位置的指针 不是目标位置。

朋友说:ff25等于call [address]导入表就是用这样call的。

  

// lmst1_1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <memory.h>
#include "ch1.h"
int gi=3;
void * address;
char * BuildCode(){
    char * p1=(char *)malloc(sizeof(char)*16);
    memset(p1,0,sizeof(char)*16);
    //mov gi,02
    *p1=0xC7;
    *(p1+1)=0x05;
      int *gi_address=(int *)(p1+2);
    *gi_address=(int)&gi;
    *(p1+6)=0x02;
    //jmp address
    *(p1+10)=0xFF;
    *(p1+11)=0x25;
    *((int *)(p1+12))= (int)&address ;
    return p1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int z;
    gi=1;
    z=Add(1,2); 
    //1. build code     
    int adress_int;
    address=&adress_int;
    _asm {
        mov address,offset label3         
    }
    void * p1=BuildCode();
    //printf("jmp address=%d \n ",address);
    printf("gi =%d \n ",gi);
    //2. jmp
    _asm {  
        jmp p1;
    }
    gi=3;
    label3:
    printf("gi=%d",gi);
    scanf("%d",&z);
       return 0;
}