求大神解答一下,强制类型转换
我在网上找了一个inline hook的例子研究了一下
红色代码部分是我把一句话分开的,我想知道为什么用这种方法获取地址,红色代码部分,就还有
ULONG temp2=(ULONG)MyMessageBoxA;这一句不明白

MyMessageBoxA的地址是0x00231690//2299536,为什么强制类型转换后变为了2298096
#include "StdAfx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
DWORD head;//保存API返回地址
int nRet;
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};//存放原始的指令
BYTE hook_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到MyMessageBoxA的指令
BYTE jmp_org_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到原起始地址后5字节的指令
int MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
int MyMessageBoxAA( HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
int MyFunc();
void Hook();
int jmp_back();
ULONG OldFuncAddr;
ULONG MyFuncAddr;
ULONG jmp_backAddr; //在修改前几个字节时,注意:取出的指令为完整的
int main()
{
Hook();
int rt = MessageBoxA(NULL, "Hello World", "Title", MB_OK);
cout << rt << endl;//查看返回值是否已修改成功
// system("pause");
return 0;
}
void Hook()
{
DWORD dwOldProtect;
OldFuncAddr = (ULONG)MessageBoxA;
// MyFuncAddr = MyMessageBoxA的实际地址
BYTE* temp=(BYTE *)MyMessageBoxA;
BYTE* TEM=(BYTE *)MyMessageBoxA+1;
ULONG* tem1=(ULONG *)(TEM);
ULONG temp1=*tem1;
ULONG temp2=(ULONG)MyMessageBoxA;
MyFuncAddr=temp1+temp2+5;
//MyFuncAddr = *(ULONG *)((BYTE *)MyMessageBoxA+1) + (ULONG)MyMessageBoxA + 5;
// jmp_backAddr = jmp_back的实际地址
jmp_backAddr = *(ULONG *)((BYTE *)jmp_back+1) + (ULONG)jmp_back + 5; //修改内存为PAGE_EXECUTE_READWRITE
VirtualProtect((LPVOID)jmp_backAddr, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect);
VirtualProtect((LPVOID)OldFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
//计算跳转地址
*((ULONG*)(hook_code+1)) = (ULONG)MyFuncAddr - (ULONG)OldFuncAddr - 5;
memcpy(orig_code,(BYTE *)OldFuncAddr, 5);
memcpy((BYTE*)OldFuncAddr, hook_code, 5);
//计算返回地址
*((ULONG*)(jmp_org_code+1)) = (ULONG)OldFuncAddr - (ULONG)jmp_backAddr - 5;
memcpy((BYTE *)jmp_backAddr, orig_code, 5);
memcpy((BYTE *)jmp_backAddr + 5, jmp_org_code, 5);
}
__declspec(naked) int jmp_back()
{
__asm
{
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
}
}
//MyMessageBoxA:在函数执行前进行自己的处理
__declspec(naked) int MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
printf("MyMessageBoxA is called\r\n");
__asm
{
pop head
pop hWnd
pop lpText
pop lpCaption
pop uType
}
MyFunc();
////可以加入函数过程
__asm
{
//压栈过程
push uType
push lpCaption
push lpText
push hWnd
push head
//跳回MessageBoxA入口点
jmp jmp_back;
ret;
}
}
//MyMessageBoxA:在函数执行后进行自己的处理
__declspec(naked) int MyMessageBoxAA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
printf("MyMessageBoxAA is called\r\n");
__asm
{
pop head
push offset s1;//返回地址为S1:
//跳回MessageBoxA入口点
jmp jmp_back;
s1: nop
}
MyFunc();
__asm
{
;//将原返回地址压栈
mov eax, 0;
////演示:将返回结果改为0,也可由MyFunc返回
push head
ret;
}
}
int MyFunc()
{
printf("Hello World\r\n");
return 1;
}
红色代码部分是我把一句话分开的,我想知道为什么用这种方法获取地址,红色代码部分,就还有
ULONG temp2=(ULONG)MyMessageBoxA;这一句不明白

MyMessageBoxA的地址是0x00231690//2299536,为什么强制类型转换后变为了2298096
#include "StdAfx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;
DWORD head;//保存API返回地址
int nRet;
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};//存放原始的指令
BYTE hook_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到MyMessageBoxA的指令
BYTE jmp_org_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到原起始地址后5字节的指令
int MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
int MyMessageBoxAA( HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
int MyFunc();
void Hook();
int jmp_back();
ULONG OldFuncAddr;
ULONG MyFuncAddr;
ULONG jmp_backAddr; //在修改前几个字节时,注意:取出的指令为完整的
int main()
{
Hook();
int rt = MessageBoxA(NULL, "Hello World", "Title", MB_OK);
cout << rt << endl;//查看返回值是否已修改成功
// system("pause");
return 0;
}
void Hook()
{
DWORD dwOldProtect;
OldFuncAddr = (ULONG)MessageBoxA;
// MyFuncAddr = MyMessageBoxA的实际地址
BYTE* temp=(BYTE *)MyMessageBoxA;
BYTE* TEM=(BYTE *)MyMessageBoxA+1;
ULONG* tem1=(ULONG *)(TEM);
ULONG temp1=*tem1;
ULONG temp2=(ULONG)MyMessageBoxA;
MyFuncAddr=temp1+temp2+5;
//MyFuncAddr = *(ULONG *)((BYTE *)MyMessageBoxA+1) + (ULONG)MyMessageBoxA + 5;
// jmp_backAddr = jmp_back的实际地址
jmp_backAddr = *(ULONG *)((BYTE *)jmp_back+1) + (ULONG)jmp_back + 5; //修改内存为PAGE_EXECUTE_READWRITE
VirtualProtect((LPVOID)jmp_backAddr, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect);
VirtualProtect((LPVOID)OldFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
//计算跳转地址
*((ULONG*)(hook_code+1)) = (ULONG)MyFuncAddr - (ULONG)OldFuncAddr - 5;
memcpy(orig_code,(BYTE *)OldFuncAddr, 5);
memcpy((BYTE*)OldFuncAddr, hook_code, 5);
//计算返回地址
*((ULONG*)(jmp_org_code+1)) = (ULONG)OldFuncAddr - (ULONG)jmp_backAddr - 5;
memcpy((BYTE *)jmp_backAddr, orig_code, 5);
memcpy((BYTE *)jmp_backAddr + 5, jmp_org_code, 5);
}
__declspec(naked) int jmp_back()
{
__asm
{
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
_emit 0x90
}
}
//MyMessageBoxA:在函数执行前进行自己的处理
__declspec(naked) int MyMessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
printf("MyMessageBoxA is called\r\n");
__asm
{
pop head
pop hWnd
pop lpText
pop lpCaption
pop uType
}
MyFunc();
////可以加入函数过程
__asm
{
//压栈过程
push uType
push lpCaption
push lpText
push hWnd
push head
//跳回MessageBoxA入口点
jmp jmp_back;
ret;
}
}
//MyMessageBoxA:在函数执行后进行自己的处理
__declspec(naked) int MyMessageBoxAA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
)
{
printf("MyMessageBoxAA is called\r\n");
__asm
{
pop head
push offset s1;//返回地址为S1:
//跳回MessageBoxA入口点
jmp jmp_back;
s1: nop
}
MyFunc();
__asm
{
;//将原返回地址压栈
mov eax, 0;
////演示:将返回结果改为0,也可由MyFunc返回
push head
ret;
}
}
int MyFunc()
{
printf("Hello World\r\n");
return 1;
}
...全文
相关推荐
java基础总结
- **强制类型转换**:当需要将较大的数据类型赋值给较小的数据类型时,需要显式地使用括号进行强制类型转换,例如 `(int) 9999999999L`。
给学生的练习题1
**Java数据类型转换**:Java中的基本数据类型转换主要分为自动类型转换和强制类型转换。自动转换发生在数值范围小的数据类型赋值给数值范围大的数据类型时,如byte到int。
2022年计算机二级考试考点C语言的几大考点介绍.docx
**强制类型转换**:强制类型转换允许我们将一个表达式的类型转换为指定类型,例如`(int)float_var`将浮点型变量转换为整型。
程序员面试题集锦
- **解答**: - 在C语言中,可以通过强制类型转换将一个地址转换为函数指针,并通过该指针调用对应地址处的代码。
全国计算机等级考试二级C语言笔试习题集答案及解析剖析.pdf
强制类型转换:当需要将一个数据类型转换为另一个数据类型时,可以使用强制类型转换。例如,`(double)x/10`将整数`x`转换为双精度浮点数再进行除法运算。9.


