首页
社区
课程
招聘
在notepad嵌入代码后运行显示没有找到.dll
发表于: 2014-3-25 11:57 4971

在notepad嵌入代码后运行显示没有找到.dll

2014-3-25 11:57
4971
想在记事本嵌入代码,运行后先显示helloworld,再执行原来的程序。
我的做法是调用原来记事本导入的messagebox函数.
结果手工嵌入后运行显示“没有找到.dll,因些无法运行程序”。
请问各位大牛哪里出问题了?我实在找不到原因。详细代码和截图在附件里
还有,我用hex workshop改代码中的地址,搞不明白push后面正确的地址是数据的RVA?还是VA?
jmp后面的地址是messagebox的RVA?
entry point也是RVA?
要用到重定位表的知识?
麻烦推荐几本经典的书。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 12502
活跃值: (5248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
偶也来关注一下介个问题
2014-3-25 14:47
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
编辑代码的时候,你那两个push后面的地址是VA。
程序代码中所有的地址都要是VA,否则怎么运行呢?
EXE程序不会进行重定位,DLL会进行重定位。
00401000 > $  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401002   .  68 00304000   push    00403000                         ; |Title = "A MessageBox !"
00401007   .  68 0F304000   push    0040300F                         ; |Text = "Hello, World !"
0040100C   .  6A 00         push    0                                ; |hOwner = NULL
0040100E   .  E8 07000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00401013   .  B8 9D730000   mov     eax, 739D
00401018   .  FFE0          jmp     eax
0040101A   $- FF25 00204000 jmp     dword ptr [<&user32.MessageBoxA>>;  user32.MessageBoxA


上面代码中:
那两个push后面的数据(00403000、0040300F)就是VA。
那个call后面是00000007,这个肯定不是地址而是一个偏移,这一句运行后EIP会向后移动7个字节,指向0040101A处的jmp指令。

另外,建议你在修改代码的时候使用OD,这样API函数地址不会出问题,静态修改太麻烦了。
2014-3-25 15:18
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
请问lixmx
静态修改中:函数调用的jmp后面Hex数据是改成函数的VA吗?
把call机器码后面的改成偏移70000000后还是显示找不到.dll啊?
哪里出问题了呢?
2014-3-25 16:25
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
所有的短跳转都可以使用长条转来代替。
如果你要使用记事本里面已经有的,那么就必须找到记事本中的IAT表,才可以使用API。

我们使用OD打开记事本程序。

01001FCF  |> \FF75 18             push    dword ptr [ebp+18]                        ; /Style
01001FD2  |.  FF75 0C             push    dword ptr [ebp+C]                         ; |Title
01001FD5  |.  FF75 10             push    dword ptr [ebp+10]                        ; |Text
01001FD8  |.  FF75 08             push    dword ptr [ebp+8]                         ; |hOwner
01001FDB  |.  FF15 68120001       call    dword ptr [<&USER32.MessageBoxW>]         ; \MessageBoxW


上面这段代码是记事本中调用MessageBoxW的代码,你可以看到那个CALL指令(FF15 68120001),他的地址是0x01001268,这个就是IAT表中MessageBoxW函数的位置。

这时候我们看一下地址0x01001268的内容(这是一个VA):
01001268 >77D66534  4e謜   USER32.MessageBoxW
0100126C >77D2C2BB  .乱w   USER32.SetWindowLongW
01001270 >77D188A6  ..褀   USER32.GetWindowLongW
01001274 >77D2436E  nC襴   USER32.GetDlgItem
01001278 >77D2B112  .币w   USER32.SetFocus
0100127C >77D2736C  ls襴   USER32.SetDlgItemTextW
01001280 >77D1A9B6  .┭w   USER32.wsprintfW
01001284 >77D24305  .C襴   USER32.GetDlgItemTextW
01001288 >77D24A4E  NJ襴   USER32.EndDialog
0100128C >77D2910F  ..襴   USER32.GetParent
01001290 >77D318AC  ..觲   USER32.UnhookWinEvent
01001294 >77D18A01  .娧w   USER32.DispatchMessageW
01001298 >77D18BF6  ?褀    USER32.TranslateMessage
0100129C >77D1941E  ..褀   USER32.TranslateAcceleratorW
010012A0 >77D27424  $t襴   USER32.IsDialogMessageW
010012A4 >77D18CCB  藢褀    USER32.PostMessageW
010012A8 >77D191C6  ?褀    USER32.GetMessageW
010012AC >77D317F7  ..觲   USER32.SetWinEventHook
010012B0  00000000  ....

可以看到第一行就是0x01001268的内容,他存放的数值是0x77D66534,就是MessageBoxW在内存中的真实地址(这个也是VA),0x01001268的内容在不同版本的Windows上是会变动的,所以你要调用MessageBoxW就只能call 0x01001268而不能直接call 0x77D66534,否者就只能在你的机器上运行,换一台机器可能就不行了。

我们在进一步确认一下,进入地址看一下啊反汇编:
77D66533    90                    nop
77D66534 >  8BFF                  mov     edi, edi
77D66536    55                    push    ebp
77D66537    8BEC                  mov     ebp, esp
77D66539    833D BC14D777 00      cmp     dword ptr [77D714BC], 0
77D66540    74 24                 je      short 77D66566
77D66542    64:A1 18000000        mov     eax, dword ptr fs:[18]
77D66548    6A 00                 push    0
77D6654A    FF70 24               push    dword ptr [eax+24]
77D6654D    68 241BD777           push    77D71B24
77D66552    FF15 C412D177         call    dword ptr [<&KERNEL32.InterlockedCompareE>; kernel32.InterlockedCompareExchange
77D66558    85C0                  test    eax, eax
77D6655A    75 0A                 jnz     short 77D66566
77D6655C    C705 201BD777 0100000>mov     dword ptr [77D71B20], 1
77D66566    6A 00                 push    0
77D66568    FF75 14               push    dword ptr [ebp+14]
77D6656B    FF75 10               push    dword ptr [ebp+10]
77D6656E    FF75 0C               push    dword ptr [ebp+C]
77D66571    FF75 08               push    dword ptr [ebp+8]
77D66574    E8 BFA2FEFF           call    MessageBoxExW
77D66579    5D                    pop     ebp
77D6657A    C2 1000               retn    10
77D6657D    90                    nop

确实是MessageBoxW的代码。

如果你要插入一个自己的消息框,那么在push四个参数之后,需要使用call 0x01001268来调用API。
另外,还要注意,XP的记事本程序中只有MessageBoxW函数的导入地址,没有MessageBoxA函数的导入地址,所以你在PUSH输入参数的时候,字符串需要用unicode字符串。
2014-3-25 16:55
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
至于说,你的程序为什么无法运行,你是不是用PEditor改过什么东西?

加代码的一半步骤:
1.找一个空白空间
2.写如自己的代码
3.自己代码的结尾处jmp到原始的入口
4.修改一下新程序的入口点

例如下面代码就可以做到弹出MsgBox框:
01008750      00                                        db      00
01008751 > $  6A 00                                     push    0                                           ; /Style = MB_OK|MB_APPLMODAL
01008753   .  68 6A870001                               push    0100876A                                    ; |Title = "test"
01008758   .  68 75870001                               push    01008775                                    ; |Text = "call MessageBoxW()"
0100875D   .  6A 00                                     push    0                                           ; |hOwner = NULL
0100875F   .  FF15 68120001                             call    dword ptr [<&USER32.MessageBoxW>]           ; \MessageBoxW
01008765   .^ E9 33ECFFFF                               jmp     0100739D
0100876A   .  7400 6500 7300 7400 0000                  unicode "test",0
01008774      00                                        db      00
01008775   .  6300 6100 6C00 6C00 2000 4D00 6500 7300   unicode "call Mes"
01008785   .  7300 6100 6700 6500 4200 6F00 7800 5700   unicode "sageBoxW"
01008795   .  2800 2900 0000                            unicode "()",0
0100879B      00                                        db      00


你把这段代码用OD敲到记事本程序里,然后修改程序入口到01008751 ,试一下。。。
如果在HEX里改记事本程序,修改地址是0x7B51开始。。。
2014-3-25 17:06
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我是用peditor修改了代码入口地址和校检和。我是把代码段的数据复制到代码段,把数据段的数据复制到数据段中。然后把用hexworkshop把push后的地址改成数据的rVA(高位在后,低位在前)。call后面的没改.还有跟call相关的那个jmp后面改为函数的RVA。

请问用hexworkshop修改push数据的rva要不要高位在后,低位在前?
call后面相关的jmp要不要清除掉? 我是调用原记事本的函数。
call 后面的偏移是不是你说的01001268减去call的下一条代码的地址?
要是用字符串没用unicode也会出错?
返回程序入口的jmp,是后面加原来的入口点,机器码是B80100739D?
机器码那些什么的我是用wdasm反汇编中看到的。
麻烦你了.
2014-3-25 18:41
0
雪    币: 2155
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
请问用hexworkshop修改push数据的rva要不要高位在后,低位在前?
call后面相关的jmp要不要清除掉? 我是调用原记事本的函数。
call 后面的偏移是不是你说的01001268减去call的下一条代码的地址?
要是用字符串没用unicode也会出错?
返回程序入口的jmp,是后面加原来的入口点,机器码是B80100739D?
机器码那些什么的我是用wdasm反汇编中看到的。

0.要使用VA,而不是RVA
1.都要低位在前。
2.要用记事本里面的jmp API,而不是你自己输入的jmp API。
3.是的,call返回地址和目的地址的差值。
4.W结尾的的API必须输入unicode,A结尾的API才可以用ANSI编码。
5.恩,你的代码执行完后,要jmp到0100739D,注意字节序地位在前。
6.机器码都一样,用什么工具看到的都一样,细微的差异不会影响阅读。

你可以在看雪的KSSD里面找资料,历年的精华贴里面也不少,从你的提问来看你的基础貌似不怎么扎实,可以补习一下汇编语言、PE文件的格式。
2014-3-25 21:03
0
游客
登录 | 注册 方可回帖
返回
//