首页
社区
课程
招聘
关于类似hook的一种方案实现 提问
发表于: 2009-12-11 16:17 4612

关于类似hook的一种方案实现 提问

2009-12-11 16:17
4612
问题已经自己解决.... 稍后整理成个心得帖吧 也算是一种成长!
1.我想做什么;
  因为不知道涉及到的具体的学术名词,姑且就结合我自身实际情况解释下.
   我们学破解,我们学外挂(不仅是游戏)无非就是对技术的一种不同运用而已,而在这条路上没有一条光明的指路灯,很欣喜的找到看雪这个宝地,能够自由的汲取知识... ... 而且被这里的氛围所感动,为了不玷污这块天堂,我一般尽量少提问,觉的事情应该自己解决,还有就怕别人指着鼻子骂,说你连这个都不会自己思考,还妄想研究破解,外挂..... 我不是怕骂我自己,而是不想让这个技术的殿堂蒙诟!
    我注册看雪的时间不长,但是我一步一步从看雪这里知道了好多好多以前不知道的新名词,了解了好多好多的新知识,并凭着兴趣和毅力一直向前努力着!如果把看雪比作一座宝藏,那么一个在宝藏中指引方向的人,对于我来说无疑最是弥足珍贵的...
    好了,大家的时间都很宝贵,无论怎样,技术无罪!
    我要做的事情就是 "游戏找CALL练习实例ONE",这个网上能找到的最普遍的外挂入门练手程序,达到效果是 1.我自己写个DLL 注入后 能够直接调用加血CALL....
                 2.继续研究,我想在这个加血CALL上做点手脚,比如我调用后 执行到我自己的函数(比如弹出个对话框等等),这个函数的功能是写日志(我自己的理解是比较接近inline hook 但是不知道对不对).然后再让程序跳回去执行!

2.我如何做的;
  1.环境 OD VC++2008  断点bp send
  2.找到加血CALL地址,地址在   0x00452e98(不同电脑位置一样,寄存器值不一样,无参调用),编程dll,注入调用,无错,通过!
   程序代码:
  
  void MyDialog::OnBnClickedButton1()
{
	MessageBox("开始吃血","开始吃血",0);

	_asm{
		  pushad;
		  mov eax, 0x00991f84;
		  mov ecx, 0x0042abe4;
		  mov edx, 0x00453028;
		  mov ebx, 0x00452e98;
		  call ebx;
		  popad;	  
	        }
	MessageBox("吃血成功","吃血成功",0);
}


     2.在00452e98处修改该内存,前7个字节,由于字节对齐和保持指令完整,实际上要覆盖掉10个字节...  
     源代码效果:
[COLOR="Blue"]00452E98      55            push ebp
00452E99      8BEC          mov ebp,esp
00452E9B      83C4 F8       add esp,-8
00452E9E      53            push ebx
00452E9F      8955 FC       mov dword ptr ss:[ebp-4],edx[/COLOR]00452EA2  |.  8BD8          mov ebx,eax
00452EA4  |.  8B45 FC       mov eax,[local.1]
00452EA7  |.  E8 1414FBFF   call 游戏找CA.004042C0
00452EAC  |.  33C0          xor eax,eax
00452EAE  |.  55            push ebp
00452EAF  |.  68 7E2F4500   push 游戏找CA.00452F7E
00452EB4  |.  64:FF30       push dword ptr fs:[eax]
00452EB7  |.  64:8920       mov dword ptr fs:[eax],esp
00452EBA  |.  8B45 FC       mov eax,[local.1]
00452EBD  |.  BA 942F4500   mov edx,游戏找CA.00452F94
00452EC2  |.  E8 5513FBFF   call 游戏找CA.0040421C
00452EC7  |.  75 2B         jnz short 游戏找CA.00452EF4


     实际执行效果:

    功能代码:
void MyDialog::OnBnClickedButton3()
{

	 MEMORY_BASIC_INFORMATION mbi;
    /*** 保存要修改地址的原有的属性信息 ***/
    DWORD dwProtect;

    /*** 查询要修改地址的属性 ***/
	if( !VirtualQuery((void *)0x0041E800, &mbi, sizeof(MEMORY_BASIC_INFORMATION)))
    if( !VirtualQuery((void *)0x006EEE00, &mbi, sizeof(MEMORY_BASIC_INFORMATION)))
    return;
    /*** 修改要悠地址的属性,主要目的在于去掉只读保护 ***/
    if( !VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwProtect)) 
        return;

    /*** 修改游戏中的指令,使其跳转到我们的函数 ***/
    //直接修改的地址
	
    *((BYTE  *)(0x00452e98)) = (BYTE)(0xB8);
    *((DWORD *)(0x00452e99)) = (DWORD)(MyTest);
    *((BYTE  *)(0x00452e9d)) = (BYTE)(0xFF);
    *((BYTE  *)(0x00452e9e)) = (BYTE)(0xE0);
    *((BYTE  *)(0x00452e9f)) = (BYTE)(0x90);
	*((BYTE  *)(0x00452ea0)) = (BYTE)(0x90);
	*((BYTE  *)(0x00452ea1)) = (BYTE)(0x90);
	///////////////////////////////////////////////////
	/*asm{
    mov esi,0x452e98
    mov byte ptr [esi],b8
    inc esi
    mov esi,MyTest
    add esi,4
    mov word ptr [esi],0x0EFF
    add esi,2
    
}*/ 
	if(!VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READ, &dwProtect))
        return;
}

我的TEST函数

void _stdcall MyTest(){   //[COLOR="red"]其实这个函数一进来就在堆栈里申请了一大块空间[/COLOR]
	_asm{
		pushad
	                pushfd
		call MyTestGUI
		popfd
		popad
		//为了补全前面丢失的代码
		//add esp,0x1C [COLOR="Red"]在这如何恢复堆栈[/COLOR]
		push ebp
		mov ebp,esp
		add esp,-8
		push ebx
		mov dword ptr ss:[ebp-4],edx
		mov eax,0x00452EA2            //计划跳回去
		jmp eax
     
		}
}

void _stdcall MyTestGUI(){
	//MessageBox(NULL,"MyTestForRun", "Test",0);
	::AfxMessageBox ("我被执行啦啦啦啦");
}




哪些原因被我基本排除了;

错误出在自己函数执行完毕返回目标程序的时候(能够执行完我写的对话框,然后回到主程序的时候再F8几步就出错).......个人认为是堆栈平衡的问题...
但是 ....我在看雪上找资料大多难以有效解决问题,一些基础还是一团浆糊...
不知道我理解的对不对 请各位指点下堆栈计算的资料.... 比如我知道PUSH 一个单字 esp-2
push一个双字 esp-4
那么pushad pushfd呢?

目标程序 游戏找CALL练习实例one.rar

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主,你有出错的error提示吗,莫非前几个地址那里内存属性为不可写,或者说你下了内存只读断点?
2009-12-11 17:43
0
雪    币: 299
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
内存我已经设置
if( !VirtualQuery((void *)0x0041E800, &mbi, sizeof(MEMORY_BASIC_INFORMATION)))
    if( !VirtualQuery((void *)0x006EEE00, &mbi, sizeof(MEMORY_BASIC_INFORMATION)))
        return;
    /*** 修改地址的属性,主要目的在于去掉只读保护 ***/
    if( !VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, &dwProtect))
        return;

能够更改代码  但是不是预期的 mov eax,0000 0000
                                            jmp eax
不知道是什么原因 注入后 程序执行会提示内存访问违规!!!!!
2009-12-12 08:42
0
雪    币: 2523
活跃值: (520)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
第2句汇编指令应该是把MyTest的地址给赋值过去了,而不是预期的mov指令
2009-12-12 09:25
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主吝啬贴代码。这个问题不难吧,但是不知道你到底想做什么,问题描叙不清啊。

楼主,这样没有需要保密内容的问题。比较复杂或者费解的问题请按以下3个步骤解释清楚再问。

我想做什么;
我如何做的;
我为什么这样做;
哪些原因被我基本排除了;

楼主自问说清楚了吗。

不知道是什么原因 注入后 程序执行会提示内存访问违规!!!!!

楼主,你肯定知道是修改后的目标程序运行时出错,还是你的程序出错。但是我们不知道,了解?

如果是修改后的目标程序运行时出错,那可能跟我以前遇到的问题一样。是由于区块属性全部被修改了,有一部分程序特别是系统类程序这样做会出错。这个可能有个前提,你的RegionSize代表是该程序在内存中的映像大小。

楼主,如果是星期一至五,我绝对不会说出上面那段话。因为你的问题,我必须用好几个可能来假定,挺累的。
2009-12-12 21:52
0
雪    币: 299
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
十分感谢怀特中肯的批评,更感谢怀特的指点,这个倒不是我吝啬贴代码,应该是我提问问题考虑的不规范,自己在研究这个东西,因为没有明确的思路,所以想到一点做一点,然后出了问题也不懂归类(因为有些API为用则用,很少知道造成的影响是什么),所以有点无法把握要害... 我再仔细自己找找原因,过后我会把问题重新整理下,再次感谢你浪费这么多时间...以后偶会踏实点的.
2009-12-14 08:46
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我也看了半天不知道什么意思、、、
2009-12-14 14:30
0
雪    币: 299
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
更新了问题...... 希望前辈解答下.........
2009-12-17 09:49
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
你 不显示对话框 显示Debug 输出不行吗?
2009-12-17 10:00
0
雪    币: 299
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
这个和对话框有关系????就是那样也要考虑堆栈吧
2009-12-17 10:03
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
最近配电脑,一直没上。

pushad是依次PUSH 8个常寄存器,就是分配8*4个堆栈空间(64位没有pushad)  POPFD 你自己用OD看下吧。
如果 楼主自己的“吃血”函数 是通过CALLXXXXXXXX    RET N方式的话就很容易看出堆栈平衡的问题。
举例: 00404010  call  408045
           00404015  XXXXXXX   (xxxxxxxx为任意指令)  
那么执行地址00404010的代码,会将地址00404015入堆,这个值在堆栈里不应被覆盖,而且其值不变。这样楼主就获得了堆栈的定位标尺,好处是很明显的。

你这个双JMP方式对 新手 不推荐。易错还不易调试代码、更改代码,时间一长忘了的话自己再看一遍也更吃力些。
2009-12-18 16:55
0
游客
登录 | 注册 方可回帖
返回
//