YJX_Driver_020_JMP地址转换公式推导

1、

向指定地址写入代码

  A、JMP地址转换公式推导

  B、计算实际地址函数RealJmp_Addr

  C、测试

【240】JMP指令 -> 机器码 --> 0xE9

【260】指令"JMP 88881234" --> 翻译成机器码 --> "E9 88881234"

  【328】打开 OD 看一下,JMP指令是否如我们上面猜想的那样翻译的

  【440】我们自己改几条指令(把它们改成JMP指令),发现 机器码后面的立即数是不同的:

    后面3个byte是相同的,第1个byte的值不同

    ZC: 应该是 JMP指令 跳转的是相对位置?

    【645】十六进制0x88881234

    【695】指令所在的地址为: 0x010073BB

      它们的差为: 0x87879E79

      【815】0x87879E79 - 0x5 ==> 0x87879E74 ==> 这就是 OD中显示的地址

      ZC: 其实 E9 后面的立即数 就是 0x88881234 与 下一条指令地址 的差,它的相对地址是 通过下一条指令 计算得来的。(想象这样一个情景,有时用OD断下(内存断点?)的时候,我们观察的是此时EIP的上面一条指令,此处应该也是这个道理?当CPU在执行A指令的时候 EIP实际已经指向了下一条指令了?EIP实际指向的是将要执行现在还没执行的指令?稍微查了一下 貌似是这样子的。于是 段内偏移 应该 是相对EIP指向的地址来计算?)

      【825】OD中的 立即数 的高地位是倒着的

        【905】看一下"dd 10073BB+1",这里 "+1"是为了跳过字节"E9"

        【1035】"db 10073BB+1"

        ZC: 饶了半天,连 CPU 小端存储格式/大端存储格式 都讲不出来么...

  【1185】

    定义JMP结构

    typedef struct _JMPCODE

    {

      BYTE E9;

      ULONG JMPADDR;

    } JMPCODE,*PJMPCODE;

    ZC: (x86)公式 应该是: 机器码相对地址=段内绝对地址 - JMP的下一条指令的地址

【1720】把 第19课 的代码复制过来

【1910】

NTSTATUS DriverEntry(PDRIVER_OBJECT _pDrvierObject, PUNICODE_STRING B)
{

  ULONG cur, old;

  cur = GetNt_CurAddr() ;

  old = GetNt_OldAddr();

  if (cur != old)

  {

    // 【2830】写入 我们的 JMP指令

    KdPrint(("NtOpenProcess被Hook了"));

  }

  else

    KdPrint(("NtOpenProcess没有被Hook"));

  _pDrvierObject->DriverUnload = DDK_Unload;
  return 1;
}

A B C

C-A-5=B //实际要写入地址

// 5B 52 65 DC

if (cur!=old)

{

JCode.E9=0xE9;

JCode.JMPADDR=cur-old-5;

KdPrint(("需要写入的地址是%X",JCode.JMPADDR));

_asm

{

mov ebx,cur

lea  ecx,JCode

mov ax,byte ptr [ecx]

mov byte ptr[ebx],ax //jmp

mov eax,[ecx+1] //B

mov [ebx+1],eax

}

//写入JMP

KdPrint(("NtOpenProcess被HOOK了"));

}

2、

时间: 2024-10-20 11:28:38

YJX_Driver_020_JMP地址转换公式推导的相关文章

python将下载地址转换成迅雷和qq旋风的下载地址

迅雷和qq旋风下载,有加速和离线功能,很方面,我是在网上看到的原始地址和迅雷地址,qq旋风地址的转化原理,然后用python+pyqt写了一个客户端 原理: 迅雷: 迅雷下载地址="thunder://"+Base64编码("AA"+"真实地址"+"ZZ") QQ旋风: qqdl="qqdl://"+Base64编码("真实地址") import re import base64 fro

手把手系列:实现Nat地址转换

1.实验目的: 掌握内网中的主机C1连接到Internet时,通过NAT实现私有全局地址转换.   2.实验拓扑: 3.实验步骤: 步骤一:给主机C1和C2配置IP地址.子网掩码和网关.如图: C1: C2: 步骤2:配置路由器R1 0/0/0端口配置如下:这个端口是内网的网关. 由于我们要在R1路由器进行nat地址转换,所以我们要在R1里写入一条规则. 规则如下: 0/0/1端口配置如下:此端口为nat转换端口,所以要写入触发规则的指令. 接着配置静态路由:目标地址为,202.100.100.

linux实现shell命令支持ipv4地址转换

这几天一直都在和IP地址打交道.GDB出来一个变量,就到计算器里面看看二进制,然后每八位的去计算得出IP地址,着实不胜其烦.搜了一下网上的信息,也没有找到类似的工具.可能大家都觉得写这么一个东西太简单了.但是其实,无论是否简单,真正能够产生便利的命令,就都是不错的命令.既然没有现成的可用,那索性就自己写一个.算来也没有几行代码. 说说这个过程的波折吧.这么简单一个程序,写出来各种问题. 1. 地址的整形表示是unsigned int .最初进行地址转换的时候调用的是atoi这个函数.试了很多次,

sockets: DNS库函数的名字与地址转换

########################################################### DNS库函数的名字与地址转换 ###################################################### 通常给出的是数值地址(也就是IP地址),不方便记忆: 域名系统(DNS):用于在主机名字和IP地址之间的映射. /etc/resolv.conf包含本地名字服务器主机的IP地址. 获取名字和地址信息的方法: 1.使用DNS 2.静态主机文件

1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

 1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端口号"就称为socket. 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接.socket本身有"插座"的意思,因此用来描述网络连 接的一对一关系. TCP/IP协议最早在BSD UNIX上实现,

字符串-06. IP地址转换

1 /* 2 * Main.c 3 * D6-字符串-06. IP地址转换 4 * Created on: 2014年8月19日 5 *******测试通过******** 6 *转载:http://blog.csdn.net/junjieguo/article/details/7392539 7 */ 8 9 10 #include <stdio.h> 11 12 int bin_dec(int x, int n) //自定义函数将二进制数转换为10进制 13 { 14 if(n == 0)

ARM中MMU地址转换理解

首先,我们要分清ARM CPU上的三个地址:虚拟地址(VA,Virtual Address).变换后的虚拟地址(MVA,Modified Virtual Address).物理地址(PA,Physical Address) 启动MMU后,CPU核对外发出虚拟地址VA,VA被转换为MVA供MMU使用,在这里MVA被转换为PA:最后通过PA读写实际设备 MMU的作用就是负责虚拟地址(virtual address)转化成物理地址(physical address). 32位的CPU的虚拟地址空间达到

字符串-06. IP地址转换(20)

一个IP地址是用四个字节(每个字节8个位)的二进制码组成.请将32位二进制码表示的IP地址转换为十进制格式表示的IP地址输出. 输入格式: 输入在一行中给出32位二进制字符串. 输出格式: 在一行中输出十进制格式的IP地址,其由4个十进制数组成(分别对应4个8位的二进制数),中间用"."分隔开. 输入样例: 11001100100101000001010101110010 输出样例: 204.148.21.114 import java.math.BigInteger; import

名字与地址转换getservbyname 与 getservbyport函数

名字与地址转换getservbyname 与 getservbyport函数 服务也通常靠名字来标志,getservbyname函数用于根据给定名字查找相应服务. #includestruct    servent *getservbyname( const char *servname, const char *protoname );成功:返回servent类型非空指针:失败:空指针:本函数返回非空指针 struct    servent{      char      *s_name;