push 0x******* retn 的应用

本文探讨了在破解过程中如何正确使用RETN指令来实现从函数调用中提前返回。详细解释了不同RETN指令(如retn、retn4、retn0C)的应用场景,以及它们如何影响堆栈指针ESP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自  http://blog.sina.com.cn/s/blog_679b38460100xhbj.html

在破解的时候,我想在一个call的头部直接返回,如何判断到底是使用retn、retn 4还是retn 0C......
是看call头部的代码吗??
我知道的只是retn xx的结果是在ESP上+xx,可似乎有时候我都用retn也没什么关系,这是为什么?

UD]Arthas
2008-04-19, 16:24:43
使用retn,
因为你说的是在call的头部返回,也就是被调用过程的第一条指令处返回(我没有曲解你的意思吧)。
这是还没有分配局部变量,也没有往堆栈中压入数值,那么esp指令指向的依然是call指令的返回地址,所以你直接返回就可以了,使用retn

xxxxxxx1 call xxxxxx10
xxxxxxx5

当执行call指令时,系统会把xxxxxxx5作为返回地址压入堆栈
而在被调用过程完成它的工作后,retn指令就是读取堆栈顶部的地址,然后返回到哪里
所以,通常情况下,在被调用过程里,分配了多少局部变量,也就是形如
add esp -xx
或着
sub esp xx
这就是在分配局部变量
最后过程最后也会释放多少
但是有时程序故意要修改返回地址让程序返回到另一个地方,最简单的就是这样
push xxxxxx20
retn
这样由于修改了堆栈数据,retn指令是只管读出堆栈顶部的值作为返回地址,我们就返回
到了xxxxxx20的地方了。


如果你要在被调用过程的中间,只是返回到原来的返回地址,那么你注意好堆栈平衡就可以了。
00404320 /$ 8B81 BC0A0000 mov eax,dword ptr ds:[ecx+0xABC] 00404326 56 push esi 00404327 |. 83F8 01 cmp eax,0x1 ; Switch (cases 1..3) 0040432A |. 75 0C jnz short zzllk.00404338 0040432C |. B8 A0000000 mov eax,0xA0 ; Case 1 of switch 00404327 00404331 |. BE 73000000 mov esi,0x73 00404336 |. EB 2C jmp short zzllk.00404364 00404338 |> 83F8 02 cmp eax,0x2 0040433B |. 75 0C jnz short zzllk.00404349 0040433D |. B8 78000000 mov eax,0x78 ; Case 2 of switch 00404327 00404342 |. BE 5A000000 mov esi,0x5A 00404347 |. EB 1B jmp short zzllk.00404364 00404349 |> 83F8 03 cmp eax,0x3 0040434C |. 75 0C jnz short zzllk.0040435A 0040434E |. B8 50000000 mov eax,0x50 ; Case 3 of switch 00404327 00404353 |. BE 41000000 mov esi,0x41 00404358 |. EB 0A jmp short zzllk.00404364 0040435A |> B8 28000000 mov eax,0x28 ; Default case of switch 00404327 0040435F |. BE 12000000 mov esi,0x12 00404364 |> 8B4C24 08 mov ecx,dword ptr ss:[esp+0x8] 00404368 |. 8B11 mov edx,dword ptr ds:[ecx] ; zzllk.0042AB68 0040436A |. 2BD0 sub edx,eax 0040436C |. B8 67666666 mov eax,0x66666667 00404371 |. F7EA imul edx 00404373 |. C1FA 04 sar edx,0x4 00404376 |. 8BC2 mov eax,edx 00404378 |. C1E8 1F shr eax,0x1F 0040437B |. 8D4402 02 lea eax,dword ptr ds:[edx+eax+0x2] 0040437F |. 85C0 test eax,eax 00404381 |. 8901 mov dword ptr ds:[ecx],eax 00404383 |. 7D 06 jge short zzllk.0040438B 00404385 |. C701 00000000 mov dword ptr ds:[ecx],0x0 0040438B |> 8339 16 cmp dword ptr ds:[ecx],0x16 0040438E |. 7C 06 jl short zzllk.00404396 00404390 |. C701 15000000 mov dword ptr ds:[ecx],0x15 00404396 |> 8B51 04 mov edx,dword ptr ds:[ecx+0x4] 00404399 |. B8 1F85EB51 mov eax,0x51EB851F 0040439E |. 2BD6 sub edx,esi 004043A0 |. 5E pop esi ; 0019F3A4 004043A1 |. F7EA imul edx 004043A3 |. C1FA 04 sar edx,0x4 004043A6 |. 8BC2 mov eax,edx 004043A8 |. C1E8 1F shr eax,0x1F 004043AB |. 8D4402 02 lea eax,dword ptr ds:[edx+eax+0x2] 004043AF |. 85C0 test eax,eax 004043B1 |. 8941 04 mov dword ptr ds:[ecx+0x4],eax 004043B4 |. 7D 07 jge short zzllk.004043BD 004043B6 |. C741 04 00000>mov dword ptr ds:[ecx+0x4],0x0 004043BD |> 8379 04 0E cmp dword ptr ds:[ecx+0x4],0xE 004043C1 |. 7C 07 jl short zzllk.004043CA 004043C3 |. C741 04 0D000>mov dword ptr ds:[ecx+0x4],0xD 004043CA \> C2 0400 retn 0x4 解释一下此函数的目的,函数输入一个指针和一个Cpoint坐标
07-08
帮我分析整理这个函数,让我好理解一点 int sub_85B450() { char *v0; // edi int v1; // eax int v2; // ebx signed int v3; // eax int v4; // esi int v5; // eax int v6; // eax int v7; // eax int v8; // esi int v9; // edi int v10; // eax int *v11; // esi int v12; // eax int v13; // esi unsigned int v14; // edx int *v15; // ecx int v16; // esi int v17; // edx _QWORD *v18; // ecx char *v19; // ebx __int16 v20; // cx _WORD *v21; // edi signed int v22; // ebx __int16 v23; // dx __int16 v24; // si __int16 v25; // dx __int16 v26; // si __int16 v27; // dx __int16 v28; // si int v29; // eax int v30; // eax int v31; // esi char *v32; // ebx int v33; // edx int v34; // ebx int v35; // ecx int v36; // eax int *v37; // edi int v38; // eax __int128 v39; // xmm0 _DWORD *v40; // ebx int v41; // esi int v42; // edx int v43; // ecx void *v44; // esi int v45; // eax char *v46; // ebx char *v47; // edx int v48; // ecx int v49; // ecx _DWORD *v50; // eax signed int v51; // edx signed int v52; // esi int v53; // ecx int result; // eax char *v55; // [esp+Ch] [ebp-3ECh] int v56; // [esp+10h] [ebp-3E8h] int v57; // [esp+14h] [ebp-3E4h] int v58; // [esp+18h] [ebp-3E0h] int v59; // [esp+1Ch] [ebp-3DCh] _DWORD *v60; // [esp+20h] [ebp-3D8h] int v61; // [esp+24h] [ebp-3D4h] int v62; // [esp+28h] [ebp-3D0h] char *v63; // [esp+2Ch] [ebp-3CCh] int v64; // [esp+30h] [ebp-3C8h] char *v65; // [esp+34h] [ebp-3C4h] int v66; // [esp+38h] [ebp-3C0h] char v67; // [esp+40h] [ebp-3B8h] char v68; // [esp+390h] [ebp-68h] CHAR Text; // [esp+3D4h] [ebp-24h] if ( dword_15A6774 ) { sub_C0B7E1((LPVOID)dword_15A6774); dword_15A6774 = 0; } sub_C10BE0(&unk_350DDE0, 0, 2195456); sub_C10BE0(&dword_EE2770, 0, 7094272); sub_C10BE0(&unk_2CE07C0, 0, 3035136); sub_C10BE0(&unk_ED88E0, 0, 18432); sub_C10BE0(&unk_1660B80, 0, &unk_167FC40); if ( dword_350DD9C != dword_350DDA0 ) { sub_86E680(dword_350DD9C); dword_350DDA0 = dword_350DD9C; } sub_C10BE0(&unk_EC0780, 0, 96); sub_C10BE0(&dword_15A6780, 0, 761856); sub_C10BE0(&dword_EC07E0, 0, 98304); v0 = 0; v63 = 0; v1 = sub_C1D5A6((int)"YBi.cfg", (int)"rb"); v2 = v1; v57 = 0; v64 = 0; if ( v1 ) { sub_C1D88C((int)&v57, 4, 1, v1); sub_C1D88C((int)&v64, 4, 1, v2); v3 = v64; dword_EC0774 = v64; if ( v64 != 151001 ) { sub_717CC0(&Text, 30, "CfgVer:%d SysVer:%d", v64); MessageBoxA(0, &Text, "Error", 0); PostMessageA(hWnd, 0x12u, 0, 0); v3 = v64; } if ( v3 >= 120000 ) { v4 = sub_C1E674(v2); sub_C1D88C((int)&v66, 852, 1, v2); sub_8661C0(0); v5 = strcmp(&v67, WindowName); if ( v5 ) v5 = -(v5 < 0) | 1; if ( v5 ) { dword_1660B74 = 0x2000; sub_C1DDBA(v2, v4, 0); v6 = dword_1660B74; } else { v6 = v66; dword_1660B74 = v66; } v7 = sub_C0B7CA(852 * v6 | -(852 * (unsigned __int64)(unsigned int)v6 >> 32 != 0)); v8 = dword_1660B74; v9 = 852 * dword_1660B74; dword_15A6774 = v7; sub_C10BE0(v7, 0, 852 * dword_1660B74); dword_EE2764 = v8 - 1; v63 = (char *)sub_C0B7CA(v9 + 64); v0 = v63; sub_C1D88C((int)v63, 852, dword_1660B74, v2); sub_C1D88C((int)&v0[852 * dword_1660B74], 64, 1, v2); } else { MessageBoxA(0, "Ybi.cfg file Error3", "Error2", 0); PostMessageA(hWnd, 0x12u, 0, 0); } sub_C1D88C((int)&dword_EE2770, 6928, 1024, v2); sub_C1D88C((int)&unk_2CE07C0, 2964, 1024, v2); v10 = 256; if ( v64 < 150200 ) v10 = 128; sub_C1D88C((int)&unk_ED88E0, 72, v10, v2); sub_C1D88C((int)&unk_1660B80, 7864, 3000, v2); sub_C1D88C((int)&unk_EC0780, 16, 6, v2); sub_C1DDBA(v2, 1056768, 1); if ( v64 < 151000 ) { v11 = &dword_15A6780; do { sub_C1D88C((int)v11, 104, 1, v2); v11 += 186; } while ( (signed int)v11 < (signed int)&word_1660780 ); } else { sub_C1D88C((int)&dword_15A6780, 744, 1024, v2); } sub_C1D88C((int)&dword_EC07E0, 96, 1024, v2); sub_C1E805(v2); } v12 = sub_C1D5A6((int)"YBdrop.cfg", (int)"rb"); v13 = v12; if ( v12 ) { sub_C1D88C((int)&unk_350DDE0, 268, 0x2000, v12); sub_C1E805(v13); } v14 = 0; do { byte_ED87E0[v14] = (v14 >> 4) & 1 | (v14 >> 2) & 0x18 | (v14 >> 1) & 0x40 | 2 * (v14 & 3 | 4 * (v14 & 4 | 2 * (v14 & 0xF8))); ++v14; } while ( (signed int)v14 < 256 ); v15 = &dword_E331E8; if ( (unsigned int)dword_E331FC > 0xF ) v15 = (int *)dword_E331E8; if ( !(unsigned __int8)sub_85BF00(v15) ) MessageBoxA(0, "Can't read Ybq.cfg file.", "WARNING", 0); sub_C10BE0(&v68, 0, 64); sub_8661C0(0); sub_8661C0(0); sub_8661C0(0); LOBYTE(v65) = 0; sub_8661C0(0); sub_8661C0(0); sub_8661C0(0); sub_8661C0(0); sub_8661C0(0); sub_8661C0(0); if ( v64 == 151001 ) { v16 = 852 * dword_1660B74; sub_C10660(dword_15A6774, v0, 852 * dword_1660B74); sub_C1CCB0(&v68, &v0[v16], 64); } v17 = 0; if ( dword_1660B74 > 0 ) { v18 = (_QWORD *)dword_15A6774; do { if ( !*v18 ) break; ++v17; v18 = (_QWORD *)((char *)v18 + 852); } while ( v17 < dword_1660B74 ); } v19 = (char *)&unk_EE2ABE; dword_15A6770 = v17; v20 = 0; v65 = (char *)&unk_EE2ABE; do { v21 = v19; v22 = 4; do { v21 += 824; v23 = *(v21 - 1030); if ( v20 >= *(v21 - 1030) ) v23 = v20; v24 = *(v21 - 824); if ( v23 >= *(v21 - 824) ) v24 = v23; v25 = v24; v26 = *(v21 - 618); if ( v25 >= *(v21 - 618) ) v26 = v25; v27 = v26; v28 = *(v21 - 412); if ( v27 >= *(v21 - 412) ) v28 = v27; v20 = v28; --v22; } while ( v22 ); v19 = v65 + 6928; v65 = v19; } while ( (signed int)v19 < (signed int)&unk_15A6ABE ); dword_2FC57D0 = v28; if ( v63 ) sub_C0B7E1(v63); v29 = strcmp(&v68, "dfficvvifvdfher89429338jwesjcnasidneufhrfdfha23p3rwe23323ncdnhj"); if ( v29 ) v29 = -(v29 < 0) | 1; if ( v29 ) { MessageBoxA(0, "Ybi.cfg Global Code Error1", "Error", 0); PostMessageA(hWnd, 0x12u, 0, 0); } v30 = sub_C1D5A6((int)"SetItem.cfg", (int)"rb"); v31 = v30; v56 = v30; if ( v30 ) { sub_C1D88C((int)&dword_EC076C, 4, 1, v30); sub_C1D88C((int)&dword_EC0770, 4, 1, v31); if ( dword_EC076C < 1 || dword_EC0770 < 1 ) { MessageBoxA(0, "SetItem.cfg Not found count", "Warning", 0); sub_C1E805(v31); } else { v32 = (char *)sub_C0B7CA(3828 * dword_EC076C | -(3828 * (unsigned __int64)(unsigned int)dword_EC076C >> 32 != 0)); v55 = v32; dword_2FC57DC = sub_C0B7CA(5108 * dword_EC076C | -(5108 * (unsigned __int64)(unsigned int)dword_EC076C >> 32 != 0)); dword_2FC57D8 = sub_C0B7CA(68 * dword_EC0770 | -(68 * (unsigned __int64)(unsigned int)dword_EC0770 >> 32 != 0)); sub_C1D88C((int)v32, 3828, dword_EC076C, v31); sub_C1D88C(dword_2FC57D8, 68, dword_EC0770, v31); sub_8661C0(0); sub_8661C0(0); v59 = 0; if ( dword_EC076C > 0 ) { v33 = 0; v34 = (int)(v32 + 232); v65 = 0; v58 = v34; do { v35 = dword_2FC57DC; v36 = *(_DWORD *)(v34 - 232); v37 = (int *)v34; v63 = 0; v62 = v33; *(_DWORD *)(dword_2FC57DC + v33) = v36; v38 = v33; *(_OWORD *)(v35 + v33 + 4) = *(_OWORD *)(v34 - 228); *(_OWORD *)(v35 + v33 + 20) = *(_OWORD *)(v34 - 212); *(_OWORD *)(v35 + v33 + 36) = *(_OWORD *)(v34 - 196); v39 = *(_OWORD *)(v34 - 180); v40 = (_DWORD *)(v34 - 164); v60 = v40; *(_OWORD *)(v35 + v33 + 52) = v39; do { v41 = dword_2FC57DC; v42 = *v40; v43 = v40[1]; *(_DWORD *)(v38 + dword_2FC57DC + 68) = *v40; *(_DWORD *)(v38 + v41 + 72) = v43; *(_DWORD *)(v38 + v41 + 76) = 0; v44 = v63; if ( *(_QWORD *)v40 ) { v45 = sub_5BD880(v42, v43); *(_DWORD *)(v62 + dword_2FC57DC + 76) = v45; } v61 = 15; v46 = &v65[(_DWORD)v44 + dword_2FC57DC + 316]; v47 = &v65[(_DWORD)v44 + dword_2FC57DC + 316]; do { *((_DWORD *)v47 - 1) = *(v37 - 1); v48 = *v37; *(_DWORD *)v47 = *v37; *((_DWORD *)v47 + 1) = v37[1]; *((_DWORD *)v47 - 2) = 0; if ( v48 ) { v49 = 0; v50 = &unk_2CE07C0; while ( *(_DWORD *)v46 != *v50 ) { v50 += 741; ++v49; if ( (signed int)v50 >= (signed int)&dword_2FC57C0 ) goto LABEL_70; } *((_DWORD *)v47 - 2) = v49; } LABEL_70: v37 += 3; v46 += 16; v47 += 16; --v61; } while ( v61 ); v40 = v60 + 2; v38 = v62 + 12; v60 += 2; v62 += 12; v63 += 240; } while ( (signed int)v63 < 4800 ); v33 = (int)(v65 + 5108); v34 = v58 + 3828; ++v59; v65 += 5108; v58 += 3828; } while ( v59 < dword_EC076C ); v31 = v56; v32 = v55; } sub_C0B7E1(v32); sub_C1E805(v31); } } else { MessageBoxA(0, "SetItem.cfg Not found", "Warning", 0); } sub_A7DF20(); v51 = 0; do { v52 = 0; do { while ( !v52 ) { v52 = 1; word_2FD24A0[v51] = word_D7AA30[v51]; word_2FD22C0[v51] = word_D7A850[v51]; word_2FD2860[v51] = word_D7A670[v51]; } v53 = v52++ + v51; word_2FD24A0[v53] = word_2FD249E[v53] + word_D7AA30[v53]; word_2FD22C0[v53] = word_2FD22BE[v53] + word_D7A850[v53]; result = (unsigned __int16)word_D7A670[v53]; LOWORD(result) = word_2FD285E[v53] + result; word_2FD2860[v53] = result; } while ( v52 < 20 ); v51 += 20; } while ( v51 < 240 ); return result; }
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值