ASM - Windows - 启动流程

时间:2014-03-12 14:39:20

标签: windows assembly createprocess

我想用纯asm开始一个过程(内联c ++ asm - >没有masm)。问题是我不知道如何获得system()函数的地址。每次我重新编译程序时,地址都会改变。那么有没有办法开始一个过程?我找到了linux的解决方案。但是execve函数只是被反汇编并内联:

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

但是Windows中的CreateProcess-和系统功能要复杂得多。那么是否有可能使用原始汇编代码创建进程。我必须做与学校描述here相同的bufferoverrun攻击。但我不知道如何获得该功能的地址以启动流程。

1 个答案:

答案 0 :(得分:0)

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

因此,Windows程序必须正式使用操作系统附带的.DLL文件中的代码。如果您编写一个不调用任何.DLL文件的.EXE文件(我试过!)Windows看到没有.DLL被调用,因此假定程序什么也不做,甚至不加载.EXE文件。

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

您可以通过简单的方式执行此操作:

call _system

(请注意,在Windows C函数中,在汇编程序中使用时会有一个尾随下划线!)

在这种情况下,链接器将创建一个包装器(这里采用AT&amp; T语法):

_system:
    jmp *__imp__system

或者您可以直接调用DLL(再次使用AT&amp; T语法):

call *__imp__system

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

- 编辑 -

如果您想将代码注入流程,您可能会发现以下问题的答案很有用:

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

每个进程都不会使用“msvcrt.dll”,但几乎所有进程都应该使用“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