能力值:
( LV2,RANK:10 )
|
-
-
2 楼
呵呵,学习下
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
哈哈,学习了!!!~
|
能力值:
( LV4,RANK:50 )
|
-
-
4 楼
跟着楼主教程步伐学习一下。
我的解法
方法一:
在CRT调用main入口处将最后一个压栈值改成0,也就是ESP+4那个参数从1改成0压入。
;修改前
00401103 |. 50 push eax
00401104 |. FF35 30994000 push dword ptr [409930]
0040110A FF35 2C994000 push dword ptr [40992C]
00401110 |. E8 EBFEFFFF call 00401000;main 函数
;修改后
00401103 |. 50 push eax
00401104 |. FF35 30994000 push dword ptr [409930]
0040110A 6A 00 push 0
0040110C 90 nop
0040110D 90 nop
0040110E 90 nop
0040110F 90 nop
00401110 |. E8 EBFEFFFF call 00401000;main函数 方法二:
调用此程序时加一个任意参数,哈哈。
另,楼主在画栈示意图的时候,可能由于从栈底复制上的去的原因,笔误了。
栈地址 栈内容
┏━━━━┳━━━━┓
┃0012FFE8┃00000000┃▲
┣━━━━╋━━━━┫┃
┃0012FFEC┃00000011┃┃由 <- 局部变量2
┣━━━━╋━━━━┫┃高
┃0012FFE0┃00000022┃┃向 <- 局部变量1
┣━━━━╋━━━━┫┃低
->┃0012FFF4┃00400209┃┃增 <- 返回地址
┣━━━━╋━━━━┫┃长
┃0012FFF8┃00000022┃┃ <- 参数2
┣━━━━╋━━━━┫┃
┃0012FFFC┃00000011┃┃ <- 参数1
┗━━━━┻━━━━┛
最顶层的两个0012FFE8 和 0012FFEC 不是递减的了。 期待其他同学的新奇答案。
|
能力值:
( LV9,RANK:280 )
|
-
-
5 楼
回复 lonkil:
已经改正,应该是0012FFF0,而不是0012FFE0。
|
能力值:
( LV3,RANK:20 )
|
-
-
6 楼
我也是小菜,借此机会,刚好拾起汇编看看。我这个main跟你的有一些区别,额。
00401000 mov eax, dword ptr [esp+4]
00401004 test eax, eax
00401006 je short 00401018
00401008 push 00407044 ; ASCII "Hello world!",CR,LF
0040100D call 00401030
00401012 add esp, 4
00401015 xor eax, eax
00401017 retn
00401018 push 00407030 ; ASCII "Hello everybody!",CR,LF
0040101D call 00401030
00401022 add esp, 4
00401025 xor eax, eax
00401027 retn
方法一:00401004 test eax, eax 修改为sbb eax,eax
方法二:00401006 je short 00401018 修改为 jne short 00401018
方法三:push 00407044 和 push 00407030这两句对调
都比较傻,不要鄙视。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
 直接ZF点两下
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
 感谢楼主的教程。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
我是小菜菜~!借此机会跟着楼主学习,我的解法是:
方法一:直接将内存00407044 的Hello world!改为Hello everybody!
00401000 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] //当前ESP=0012FF84
00401004 |. 85C0 TEST EAX,EAX
00401006 |. 74 10 JE SHORT reales.00401018
00401008 68 44704000 PUSH reales.00407044 ; ASCII "Hello world!
"
0040100D |. E8 1E000000 CALL reales.00401030
00401012 |. 83C4 04 ADD ESP,4
00401015 |. 33C0 XOR EAX,EAX
00401017 |. C3 RETN
00401018 |> 68 30704000 PUSH reales.00407030 ; ASCII "Hello everybody!
"
0040101D |. E8 0E000000 CALL reales.00401030
00401022 |. 83C4 04 ADD ESP,4
00401025 |. 33C0 XOR EAX,EAX
00401027 \. C3 RETN
方法二:将ESP+4(ESP=0012FF84)处的内容改为0(程序在执行时会将自己的路径保存到argv字符数组里的,因此argc的值肯定都是始终大于1,那么argc参数的值改为0,也达到同样的效果)
各位见笑了~!
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
学习一下。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
呵呵,学习了。除了文章中说的两种方法外,第三种就是对调压入的参数顺序,如yasm所说:push 00407044 和 push 00407030这两句对调
|
能力值:
( LV3,RANK:30 )
|
-
-
12 楼
整理整理 只是为了理清下思路:
原程序:
00401000 CMP DWORD PTR SS:[ESP+4], 0
00401005 JE SHORT Test_0.00401018
00401007 PUSH Test_0.004020F4 ; /format = "Hello world!
0040100C CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
00401012 ADD ESP, 4
00401015 XOR EAX, EAX
00401017 RETN
00401018 PUSH Test_0.00402104 ; /format = "Hello everybody!
0040101D CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
00401023 ADD ESP, 4
00401026 XOR EAX, EAX
00401028 RETN
修改方法:
1.如lz所说 JE SHORT Test_0.00401018// 改jmp .......
2.修改内存004020F4地址的文本信息为“Hello everybody!”
3.00401007至00401012填充为nop 然后在00401007处加上一句mov [esp],00401018即可,这样当它执行retn指令时就会返回到00401018处(这个有点巧妙!)
4.就像 yasm 所说 PUSH Test_0.004020F4 与PUSH Test_0.00402104 对换
不知道还有什么巧妙的方法没?
|
能力值:
(RANK:10 )
|
-
-
13 楼
谢绝自带酒水
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
和楼主学习了很多知识,谢谢。支持楼主再写。
ps:作者的答案,有一点不解
答案:
各位回答的都很不错,不管用的是什么方法,只要解决问题了就是好方法。我在这里就在公布另一个方法,此方法与本节课程联系较大:
第一步、00401007至00401012填充为nop
第二步、在00401007处加上一句mov [esp],00401018即可,这样当它执行retn指令时就会返回到00401018处。
在这个第二步中,在00401007处加上一句mov [esp],00401018,确实可以执行到00401018处,但是从00401018调用处返回时,即在00401028处返回时,栈已经是乱的了,个人想法是在00401007这句指令是否应该改成push 401018更好,这样在00401028返回时可以再返回原来调用main函数的地方,即401192处,再执行exit。
个人见解,请各位老鸟指正。
|
能力值:
( LV9,RANK:280 )
|
-
-
15 楼
我们先看原来的反汇编代码:
00401007 PUSH Test_0.004020F4 ; /format = "Hello world!
0040100C CALL DWORD PTR DS:[<&MSVCR90.printf>] ; \printf
00401012 ADD ESP, 4
我们如果将其nop掉之后,main函数内的唯一一个影响堆栈的操作就已经没有了,所以我们此时只需要修改一下返回地址就可以。
如果按照你的方法,会在返回地址前压入一个你想要的返回地址,此时的栈才真正的乱了。
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
感谢你的回帖。
我还是没有明白。
我贴一下我改完后的代码,加了点注释,请指教。
00401000 837C24 04 00 cmp dword ptr [esp+4], 0
00401005 74 11 je short 00401018
00401007 68 18104000 push 00401018 //从这里开始改的,push前栈顶是main函数调用后要返回的地址00401192,再压入一个00401018
0040100C 90 nop
0040100D 90 nop
0040100E 90 nop
0040100F 90 nop
00401010 90 nop
00401011 90 nop
00401012 90 nop
00401013 90 nop
00401014 90 nop
00401015 33C0 xor eax, eax
00401017 C3 retn //这里的retn,返回调用00401018处代码,栈顶再变成00401192
00401018 68 04214000 push 00402104 ; ASCII "Hello everybody!",CR,LF
0040101D FF15 A0204000 call dword ptr [<&MSVCR90.printf>] ; MSVCR90.printf
00401023 83C4 04 add esp, 4
00401026 33C0 xor eax, eax
00401028 C3 retn //根据栈顶,返回00401192,调用main函数的后一句代码
|
能力值:
( LV9,RANK:280 )
|
-
-
17 楼
[QUOTE=zzycqok;817375]感谢你的回帖。
我还是没有明白。
我贴一下我改完后的代码,加了点注释,请指教。
00401000 837C24 04 00 cmp dword ptr [esp+4], 0
00401005 74 11 je short 0040101...[/QUOTE]
又仔细思考了一下,你的方案没错,是我的方案错了。
非常感谢这位朋友的反馈
|
能力值:
( LV2,RANK:10 )
|
-
-
18 楼
 ,感谢你的无私奉献,以及你的认真精神。
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
简单易懂,回顾了一下……
看帖留名……
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
学习学习
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
学习啦
不错的东西啦
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
首先感谢lz写这么好的入门文章。
我谈一下自己对解答的看法。
1。jmp虽然暴力,但同时的确是可以实实在在的改变程序的显示。
2。改内存改字符串的的办法,实在是有违逆向的精神。
3。push地址 retn 的确是比较经典的做法。这一招俺学到了(窃喜)。
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
直接把PUSH Test_0.004020F4 改成PUSH Test_0.00402104 就OK了 ,不知道是否违反逆向,请老鸟指点。
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
通俗易懂。支持大仙
|
能力值:
( LV2,RANK:10 )
|
-
-
25 楼
好,学习了~~~~~
|
|
|