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


    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 
     ",address);
        printf("gi =%d 
     ",gi);
        //2. jmp
        _asm {  
            jmp p1;
        }
        gi=3;
        label3:
        printf("gi=%d",gi);
        scanf("%d",&z);
           return 0;
    }
  • 相关阅读:
    冲刺周期第七天
    软件体系架构课下作业01
    大型网站技术架构-核心原理与案例分析-阅读笔记6
    大型网站技术架构-核心原理与案例分析-阅读笔记5
    大型网站技术架构-核心原理与案例分析-阅读笔记4
    大型网站技术架构-核心原理与案例分析-阅读笔记3
    大型网站技术架构-核心原理与案例分析-阅读笔记02
    《大型网站技术架构核心原理与案例分析》阅读笔记-01
    掌握需求过程阅读笔记—3
    掌握需求过程阅读笔记—2
  • 原文地址:https://www.cnblogs.com/facingwaller/p/3560107.html
Copyright © 2020-2023  润新知