工具:IDA 6.8

示例:MBE的lab1B

main:

.text:08048BE4 000                 push    ebp
.text:08048BE5 004                 mov     ebp, esp
.text:08048BE7 004                 and     esp, 0FFFFFFF0h
.text:08048BEA 004                 sub     esp, 20h
.text:08048BED 024                 push    eax
.text:08048BEE 028                 xor     eax, eax
.text:08048BF0 028                 jz      short loc_8048BF5
.text:08048BF2 028                 add     esp, 4
.text:08048BF5
.text:08048BF5     loc_8048BF5:                            ; CODE XREF: main+Cj
.text:08048BF5 024                 pop     eax
.text:08048BF6 020                 mov     dword ptr [esp], 0 ; timer
.text:08048BFD 020                 call    _time
.text:08048C02 020                 mov     [esp], eax      ; seed
.text:08048C05 020                 call    _srand
.text:08048C0A 020                 mov     dword ptr [esp], offset a__ ; ".---------------------------."
.text:08048C11 020                 call    _puts
.text:08048C16 020                 mov     dword ptr [esp], offset aRpisecCrackmeV ; "|-- RPISEC - CrackMe v2.0 --|"
.text:08048C1D 020                 call    _puts
.text:08048C22 020                 mov     dword ptr [esp], offset asc_8048DC4 ; "'---------------------------'"
.text:08048C29 020                 call    _puts
.text:08048C2E 020                 mov     dword ptr [esp], offset format ; "\nPassword: "
.text:08048C35 020                 call    _printf
.text:08048C3A 020                 lea     eax, [esp+1Ch]
.text:08048C3E 020                 mov     [esp+4], eax
.text:08048C42 020                 mov     dword ptr [esp], offset aD ; "%d"
.text:08048C49 020                 call    ___isoc99_scanf
.text:08048C4E 020                 mov     eax, [esp+1Ch]
.text:08048C52 020                 mov     dword ptr [esp+4], 1337D00Dh
.text:08048C5A 020                 mov     [esp], eax
.text:08048C5D 020                 call    test
.text:08048C62 020                 mov     eax, 0
.text:08048C67 020                 leave
.text:08048C68 -04                 retn
.text:08048C68     main            endp ; sp-analysis failed

loc_8048BF5的部分实际没有执行,但是IDA显示的栈顶从028变到了024,看后面的retn,栈顶是-04(大概这就是堆栈不平衡?)

直接F5的话,会显示:

error of " positive sp value has been found"

于是在“loc_8048BF5:”那一行改变sp的值,将“difference between old and new sp”设置成“0x0”:

.text:08048BF5 024                 pop     eax                ;这一句还是024,没有变成028
.text:08048BF6 024                 mov     dword ptr [esp], 0 ;但是这一句从020变成了020
.text:08048BFD 024                 call    _time

看后面的retn,栈顶是000。那么堆栈应该就平衡了。

F5试试:

int __cdecl main(int argc, const char **argv, const char **envp)
{unsigned int v3; // eax@1int v5; // [sp+1Ch] [bp-4h]@1v3 = time(0);srand(v3);puts(".---------------------------.");puts("|-- RPISEC - CrackMe v2.0 --|");puts("'---------------------------'");printf("\nPassword: ");__isoc99_scanf("%d", &v5);test(v5, 322424845);return 0;
}

再看看test函数:

int __cdecl test(int a1, int a2)
{int result; // eax@2int v3; // eax@23int v4; // [sp+1Ch] [bp-Ch]@1v4 = a2 - a1;switch ( a2 - a1 ){case 1:result = decrypt(v4);break;case 2:result = decrypt(v4);break;case 3:result = decrypt(v4);break;case 4:result = decrypt(v4);break;case 5:result = decrypt(v4);break;case 6:result = decrypt(v4);break;case 7:result = decrypt(v4);break;case 8:result = decrypt(v4);break;case 9:result = decrypt(v4);break;case 10:result = decrypt(v4);break;case 11:result = decrypt(v4);break;case 12:result = decrypt(v4);break;case 13:result = decrypt(v4);break;case 14:result = decrypt(v4);break;case 15:result = decrypt(v4);break;case 16:result = decrypt(v4);break;case 17:result = decrypt(v4);break;case 18:result = decrypt(v4);break;case 19:result = decrypt(v4);break;case 20:result = decrypt(v4);break;case 21:result = decrypt(v4);break;default:v3 = rand();result = decrypt(v3);break;}return result;
}

再看看decrypt函数:

失败了:

error of " positive sp value has been found"

看看decrypt函数的汇编:
.text:080489B7 000                 push    ebp
.text:080489B8 004                 mov     ebp, esp
.text:080489BA 004                 sub     esp, 38h
.text:080489BD 03C                 mov     eax, large gs:14h
.text:080489C3 03C                 mov     [ebp+var_C], eax
.text:080489C6 03C                 xor     eax, eax
.text:080489C8 03C                 mov     dword ptr [ebp+s], 757C7D51h
.text:080489CF 03C                 mov     [ebp+var_19], 67667360h
.text:080489D6 03C                 mov     [ebp+var_15], 7B66737Eh
.text:080489DD 03C                 mov     [ebp+var_11], 33617C7Dh
.text:080489E4 03C                 mov     [ebp+var_D], 0
.text:080489E8 03C                 push    eax
.text:080489E9 040                 xor     eax, eax
.text:080489EB 040                 jz      short loc_80489F0
.text:080489ED 040                 add     esp, 4
.text:080489F0
.text:080489F0     loc_80489F0:                            ; CODE XREF: decrypt+34j
.text:080489F0 03C                 pop     eax
.text:080489F1 038                 lea     eax, [ebp+s]
.text:080489F4 038                 mov     [esp], eax      ; s
.text:080489F7 038                 call    _strlen
.text:080489FC 038                 mov     [ebp+var_24], eax
.text:080489FF 038                 mov     [ebp+var_28], 0
.text:08048A06 038                 jmp     short loc_8048A28
.text:08048A08     ; ---------------------------------------------------------------------------
.text:08048A08
.text:08048A08     loc_8048A08:                            ; CODE XREF: decrypt+77j
.text:08048A08 038                 lea     edx, [ebp+s]
.text:08048A0B 038                 mov     eax, [ebp+var_28]
.text:08048A0E 038                 add     eax, edx
.text:08048A10 038                 movzx   eax, byte ptr [eax]
.text:08048A13 038                 mov     edx, eax
.text:08048A15 038                 mov     eax, [ebp+arg_0]
.text:08048A18 038                 xor     eax, edx
.text:08048A1A 038                 lea     ecx, [ebp+s]
.text:08048A1D 038                 mov     edx, [ebp+var_28]
.text:08048A20 038                 add     edx, ecx
.text:08048A22 038                 mov     [edx], al
.text:08048A24 038                 add     [ebp+var_28], 1
.text:08048A28
.text:08048A28     loc_8048A28:                            ; CODE XREF: decrypt+4Fj
.text:08048A28 038                 mov     eax, [ebp+var_28]
.text:08048A2B 038                 cmp     eax, [ebp+var_24]
.text:08048A2E 038                 jb      short loc_8048A08
.text:08048A30 038                 mov     dword ptr [esp+4], offset s2 ; "Congratulations!"
.text:08048A38 038                 lea     eax, [ebp+s]
.text:08048A3B 038                 mov     [esp], eax      ; s1
.text:08048A3E 038                 call    _strcmp
.text:08048A43 038                 test    eax, eax
.text:08048A45 038                 jnz     short loc_8048A55
.text:08048A47 038                 mov     dword ptr [esp], offset command ; "/bin/sh"
.text:08048A4E 038                 call    _system
.text:08048A53 038                 jmp     short loc_8048A61
.text:08048A55     ; ---------------------------------------------------------------------------
.text:08048A55
.text:08048A55     loc_8048A55:                            ; CODE XREF: decrypt+8Ej
.text:08048A55 038                 mov     dword ptr [esp], offset s ; "\nInvalid Password!"
.text:08048A5C 038                 call    _puts
.text:08048A61
.text:08048A61     loc_8048A61:                            ; CODE XREF: decrypt+9Cj
.text:08048A61 038                 mov     eax, [ebp+var_C]
.text:08048A64 038                 xor     eax, large gs:14h
.text:08048A6B 038                 jz      short locret_8048A72
.text:08048A6D 038                 call    ___stack_chk_fail
.text:08048A72     ; ---------------------------------------------------------------------------
.text:08048A72
.text:08048A72     locret_8048A72:                         ; CODE XREF: decrypt+B4j
.text:08048A72 038                 leave
.text:08048A73 -04                 retn

看到:

.text:080489ED 040                 add     esp, 4
.text:080489F0
.text:080489F0     loc_80489F0:                            ; CODE XREF: decrypt+34j
.text:080489F0 03C                 pop     eax
.....................................................................


.text:08048A73 -04                 retn

和之前是一样的问题。
重复上次类似的操作,然后F5:
int __cdecl decrypt(char a1)
{size_t i; // [sp+10h] [bp-28h]@1size_t v3; // [sp+14h] [bp-24h]@1char s[4]; // [sp+1Bh] [bp-1Dh]@1int v5; // [sp+2Ch] [bp-Ch]@1v5 = *MK_FP(__GS__, 20);strcpy(s, "Q}|u`sfg~sf{}|a3");v3 = strlen(s);for ( i = 0; i < v3; ++i )s[i] ^= a1;if ( !strcmp(s, "Congratulations!") )system("/bin/sh");elseputs("\nInvalid Password!");return *MK_FP(__GS__, 20) ^ v5;
}

成功了。

MBE的lab1A也是类似的。在main部分,auth部分分别调整一次sp值,就使堆栈平衡了。
总结:
程序通过一个实际不会执行的语句:
add     esp, 4

导致IDA分析错误,修改了栈顶,使retn时的栈顶是-004,一个过程前后的栈顶不一样,堆栈不平衡。

那么手动修改esp的值,将“add esp, 4”后的栈顶改回来,就好了。

[RE]如何调整堆栈平衡相关推荐

  1. 从汇编角度理解 ebpesp 寄存器、函数调用过程、函数参数传递以及堆栈平衡

    关于函数参数的传递及堆栈指针的变化,一直缺乏系统的认识和了解,各种博客也只是片面的讲解某个局部知识点,并没有全局的把握和对栈的深刻理解.本文试图从汇编以及整体上,讲解函数调用时,堆栈的变化,以及到底是 ...

  2. 【汇编语言与计算机系统结构笔记15】子程序设计:调用与返回,保护与恢复寄存器,子程序的参数传递,堆栈平衡,结构伪操作 STRUC

    本次笔记内容: 20.子程序设计-1-1 21.子程序设计-1-2 22.子程序设计-1-3 注:我找到了对应内容的课件,请见我于GitHub的CS笔记仓库.因此,为了节省时间,我只记录老师上课强调的 ...

  3. ESP定律和堆栈平衡

    一.什么是ESP 二. 例说ESP与OD的对比 三. 正式开讲ESP定律 四. ESP定律的运行栗子 五. 堆栈平衡讲解 六.ESP定律的变形用法

  4. 中国计算机市场调整中平衡增长 (转)

    中国计算机市场调整中平衡增长 (转)[@more@] 2002年,中国计算机市场实现销售额2358.4亿元,比2001年增长16.0%,与2001年增长率16.8%相比,下降了0.8个百分点,这表明中 ...

  5. 堆栈平衡:估计这是最详细的讲解堆栈平衡的了 vc++6.0

    转自:https://blog.csdn.net/lixiangminghate/article/details/43195717 #include <stdio.h> #include ...

  6. 汇编达人视频学习6(汇编眼中的函数、CALL指令执行函数、堆栈传参、堆栈平衡、外平栈、内平栈)

    title: 汇编达人视频学习6 date: 2021年8月4日 15点15分 tags: 汇编达人 categories: 汇编达人 21.汇编眼中的函数 1.什么是函数 函数就是一系列指令的集合, ...

  7. 在地址随机化的操作系统环境下的堆栈平衡

    最近学习汇编以及各种和汇编有关系的课,在看汇编代码的时候发现各种对esp啊ebp的操作,最后的目的很多是为了堆栈平衡,因为如果函数调用之前和之后的堆栈不一致,就可能导致找不到数据或者找错数据.然后就想 ...

  8. 调用函数后的堆栈平衡

    对于__stdcall调用方式,调用函数的逻辑一般如下 //Caller;prolog push xx push ... call callee add esp x ; 恢复堆栈 ;epilog 一般 ...

  9. 浅谈安卓逆向月报(1)- 抖音 - ida - native层F5伪代码堆栈平衡修复

    这章主要聊聊如何修复可以F5伪代码 以最新的抖音840的so为例,这边仅仅说下如何修复F5,解决"positive sp value has been found"错误提示. 后续 ...

  10. vs调用堆栈窗口怎么弄出来_从零开始(1)栈帧、调用约定

    逆向学习从零开始(1)栈帧.调用约定明白函数和寄存器.栈的关系 PE程序拖入OD有四个基础窗口:代码执行窗口.寄存器窗口.数据窗口.栈窗口,帮助我们对程序进行逆向分析,运行程序,处理器执行的是汇编代码 ...

最新文章

  1. ZStack源码剖析之核心库鉴赏——FlowChain
  2. 金融专有云数据安全实践
  3. ACM常见问题之【求逆序对】
  4. JZOJ 5195. 【NOIP2017提高组模拟7.3】A
  5. Sitecore 个性化 - 近距离和过于个人化?
  6. SpringBoot2.x 整合websocket 消息推送,单独发送信息,群发信息
  7. js做的flash形式的幻灯图片
  8. 商业智能数据营销该怎么做?
  9. java i o是什么流_Java I/O 流,输入流、输出流
  10. UVA10344 23 out of 5【暴力+DFS】
  11. 想打造一款成功的移动应用?你最需要关注性能指标!
  12. ffmpeg之vs编译
  13. The pricess diaries
  14. 智慧职教云Java题库_智慧职教作业的答案,云课堂智慧职教java职业证书题库答案,职教云智慧职教题库答案...
  15. html5在线+网站,15个在线HTML5网页设计工具
  16. Java中基于Rxtx的串口操作
  17. python爬虫方向的第三方库,Python网络爬虫方向的第三方库是
  18. 单例模式如何确保线程安全
  19. 使用 Docker 部署 MediaWiki
  20. mysql every derived table must_Mysql错误Every derived table must have its own alias解决方法

热门文章

  1. OpenCV C++案例实战二十《银行卡号识别》
  2. 开关电容共模反馈学习
  3. 什么是物联网(IoT)?
  4. 分仓软件是什么?资管分仓的作用
  5. html选择日期选择器
  6. 关于瑞昱8763bfr的学习总结(1)
  7. 论文阅读笔记 | 分类网络——ParNet
  8. 6轴工业机器人机械手的控制方式及特点
  9. 微信小程序从入门到放弃(五)
  10. FlashFXP连接虚拟机ubuntu 16.04