2014-03-12 22 views
0

我想用纯的asm(inline C++ asm - > no masm)启动一个进程。问题是我不知道如何获得system()函数的地址。每次我重新编译程序,地址都会改变。那么有什么办法可以启动一个流程?我找到了一个针对linux的解决方案。但在execve的功能只是被拆卸和内联:ASM - Windows - 启动过程

0x80002bc <__execve>: pushl %ebp 
0x80002bd <__execve+1>: movl %esp,%ebp 
0x80002bf <__execve+3>: pushl %ebx 
0x80002c0 <__execve+4>: movl $0xb,%eax 
0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx 
0x80002c8 <__execve+12>:  movl 0xc(%ebp),%ecx 
0x80002cb <__execve+15>:  movl 0x10(%ebp),%edx 
0x80002ce <__execve+18>:  int $0x80 
0x80002d0 <__execve+20>:  movl %eax,%edx 
0x80002d2 <__execve+22>:  testl %edx,%edx 
0x80002d4 <__execve+24>:  jnl 0x80002e6 <__execve+42> 
0x80002d6 <__execve+26>:  negl %edx 
0x80002d8 <__execve+28>:  pushl %edx 
0x80002d9 <__execve+29>:  call 0x8001a34 <__normal_errno_location> 
0x80002de <__execve+34>:  popl %edx 
0x80002df <__execve+35>:  movl %edx,(%eax) 
0x80002e1 <__execve+37>:  movl $0xffffffff,%eax 
0x80002e6 <__execve+42>:  popl %ebx 
0x80002e7 <__execve+43>:  movl %ebp,%esp 
0x80002e9 <__execve+45>:  popl %ebp 
0x80002ea <__execve+46>:  ret 
0x80002eb <__execve+47>:  nop 

见:http://insecure.org/stf/smashstack.html

但CreateProcess-和Windows中的系统功能要复杂得多。那么是否有可能用原始汇编代码创建一个进程?我必须要做与学校描述的here相同的缓冲区溢出攻击。但我不明白如何获得该函数的地址来启动一个进程。

+0

Windows有安全措施来阻止你这样做。对于可能用于绕过这些措施的技术的讨论对于堆栈溢出问题来说太长了。投票结束。 –

+0

好吧。我真的得到它的工作。但是我不得不使用VirtualAlloc函数来使代码可执行。 –

+0

@ florian-r但是......但是......你是怎么做到的? –

回答

0

首先您应该知道Windows操作系统内部在Linux中使用类似于“int 0x80”的机制(它是Windows NT 4.x中的“int 0x2E”),但此机制不是官方的,因此可能会更改从版本到版本。

因此,Windows程序必须正式使用操作系统附带的.DLL文件中的代码。如果你编写一个不调用任何.DLL文件的.EXE文件(我试过!),Windows发现没有.DLL被调用,因此认为该程序根本不会执行任何操作,甚至不会加载.EXE文件。

这意味着您必须调用Windows下.DLL文件中定义的函数。

您可以在此做简单的方法:

call _system 

(请注意,在Windows下的C函数在汇编使用时尾随下划线!)

在这种情况下,连接器会创建一个包装(这里在& T语法):

_system: 
    jmp *__imp__system 

或者你可以再次& T语法直接调用DLL(在):

call *__imp__system 

您必须链接到.DLL文件(例如, “_system”的msvcrt.dll)。

- 编辑 -

如果你想将代码注入进程可能会找到你以下问题有用:

How to find DLL's loaded into a process and it's location, etc

“MSVCRT.DLL”不是neccessarily每个进程都使用它,但是“kernel32.dll”几乎应该被所有进程使用。

“kernel32.dll”包含“LoadLibraryA”,因此您可以加载“msvcrt.dll”或直接使用“CreateProcessA”(来自kernel32.dll)。

的从DLL文件中的函数的入口点开始的偏移量始终是一样的,所以你可以计算出:

address_of_function_in_debugged_process = 
    address_of_function_in_debugger - 
    DLL_address_in_debugger + /* should be equal to the DLL HINSTANCE */ 
    DLL_address_in_debugged_process 
+0

感谢您的回答。但它并不能真正解决我的问题。由于汇编代码被注入到正在运行的进程中,“call _system”将不起作用。据我所见,“call _system”被翻译成“call [adressofsystem]”之类的东西。但是地址会不时变化,所以我不能使用这样的东西。我真的需要使用interupt ...但我找不到任何有关这方面的信息。这仍然支持在Windows 8中? –