首页
社区
课程
招聘
代码自定位 获取LoadLibrary的问题
2011-2-11 22:01 12436

代码自定位 获取LoadLibrary的问题

2011-2-11 22:01
12436
哥们, 我第一次上来发帖, 问个问题, 这个问题比较麻烦, 一时还不大好说的清. 我慢慢说, 我想让一个程序完全脱离
程序执行, 并且不调用任何的API函数, 这是可以做到的, 罗云彬的书上有很详细的讲解, 下面我把我的代码贴出来,
我遇到的问题主要是除了kernel32外任何的API函数都不能够使用. 按说用LoadLibrary导入其他的DLL就可以使用其他
DLL的函数了,事实上也确实是这样, 因为我看<<windows 环境下32位汇编语言程序设计>>也是这样做的, 但是我这里这个
代码却不知道出了什么问题? OD调试了很久也看不出问题. 大侠就指点了, 我表达能力非常有限, 我把代码贴出来了啊,
有好心的大侠就看看啊!

Include masm32rt.inc
Include JoenWin.inc
        .code
       
;获取Kernel的基址 ecx, 中存放kernel的基址,
CodeStart:

        Include JGetApiAddr.asm

;********************************************************************************
;存放函数字符串
;********************************************************************************
szLoadLibrary                byte         "LoadLibraryA",0
szGetProcAddress         byte        "GetProcAddress",0
szGetModuleHandle        byte        "GetModuleHandleA", 0
szExitProcess                byte        "szExitProcess", 0
szAllocConsole                byte        "AllocConsole", 0
szUser32                byte        "user32.dll", 0, 0, 0

szMessageBox                byte        "MessageBoxA", 0
;********************************************************************************
;存放地址
;********************************************************************************
hKernelModule                dword        ?
hUser32Module                dword        ?

lpLoadLibrary                dword        ?        ;这2个地址尤其重要的
lpGetProcAddress        dword        ?

lpMessageBox                dword        ?        ;MessageBox的地址
lpAllocConsole                dword        ?
lpExitProcess                dword        ?

Entry:
        mov        ecx, edx                        ;这里是CreateProcess的入口
       
        call        @f                                ;自定位
        @@:
        pop        ebx
        sub        ebx, offset @b
       
       
        invoke        JgetKernelBase, ecx
        ;push        ecx
        ;mov        eax, [ebx+ offset JgetKernelBase]
        ;call        JgetKernelBase                                ;获取Kernel32的基址
       
               
        mov        [ebx+ hKernelModule], eax                ;保存下kernel的地址
       
       
        lea        esi, [ebx+offset szGetProcAddress]
        invoke        JGetApi, [ebx+hKernelModule],esi        ;获取GetProcAddress的地址
       
        mov        [ebx+offset lpGetProcAddress], eax        ;保存GetProcAddress的地址
       
        lea        esi, [ebx+offset szLoadLibrary]                ;获取LoadLibrary的地址
        push        esi
        push        [ebx+hKernelModule]
        call        [ebx+offset lpGetProcAddress]
        mov        [ebx+offset lpLoadLibrary], eax
       
        lea        esi, [ebx+offset szAllocConsole]        ;获取AllocConsole的地址
        push        esi
        push        [ebx+hKernelModule]
        call        [ebx+offset lpGetProcAddress]
        mov        [ebx+offset lpAllocConsole],eax
       
       
        lea        esi, [ebx+ offset szUser32]               
        push        esi
        mov        edx, [ebx+offset lpLoadLibrary]
        call        @f
        @@:
        jmp        edx                                                
;到底要怎么样才可以呢?, 我试过很多次, 有时候可以有时候又, 不可以. 这是哪里出问题了?

       
        mov        [ebx+hUser32Module], eax                ;问题就在这里, 我CALL的地址也是对的啊, 我RP有问题???
       
        lea        esi, [ebx+offset szMessageBox]                ;如果逻辑正确, 这里就可以获取MessageBox的地址了
        push        esi
        push        [ebx+hUser32Module]
        call        [ebx+offset lpGetProcAddress]
        mov        [ebx+offset lpMessageBox], eax
       
        push        0
        push        [ebx+offset szMessageBox]                ;然后CALLMessageBox
        push        [ebx+offset szMessageBox]
        push        0
        call        eax
       
       
        lea        esi, [ebx+offset szExitProcess]                ;获取ExitProcess的地址
        push        esi
        push        [ebx+hKernelModule]
        call        [ebx+offset lpGetProcAddress]
        mov        [ebx+offset lpExitProcess], eax
       
        push        0                                        ;程序退出
        call        eax
       
       
               
CodeEnd:       

;代码长度
CODELENGTH         equ        CodeEnd - CodeStart
CODEENTRY        equ         Entry - CodeStart        

Jmain:
       
        mov        edx, [esp]                        ;保留好esp的值, 这里kernel的根本啊
       
        sub        esp, CODELENGTH
        mov        esi, CodeStart
        mov        ecx, CODELENGTH                        ;复制代码到堆栈中
        mov        edi, esp
        rep        movsb
       
        mov        eax, esp
        add        eax, CODEENTRY                        ;求出代码执行的偏移
        jmp        eax
       
end        Jmain

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞6
打赏
分享
最新回复 (11)
雪    币: 38
活跃值: (47)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
lyricC 2011-2-11 22:31
2
0
"让一个程序完全脱离程序执行"-----??????????????????????????????????????
我真的是不懂。我一直都在怀疑我的语文功底,现在我可以确认我的语文水平确实到了无可救药的地步。什么c什么c++什么java,一切都是浮云,我还是回家学语文吧
雪    币: 6991
活跃值: (1217)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
JoenChen 4 2011-2-11 22:34
3
0
楼上这位, 我表达能力, 不是很好, 就不要笑我了, 大概知道是什么意思就好了!
雪    币: 2321
活跃值: (4018)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
熊猫正正 9 2011-2-11 22:41
4
0
利用Call 实现的动态定位~顶一个,嘿嘿
  call  @f        ;自定位
@@:
  pop  ebx
  sub  ebx, offset @b
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小阿呆xy 2011-2-11 22:57
5
0
  完全不用api函数?这好像不可能的吧?除非你自已写底层驱动来实现,不过那工作量,呃。看你的意思,好像是说不用输入表而已啊。不过我一直不明白这样做有什么用,表面上没导入,可实际上还是用了,这类技术通常只用在病毒上。以前看过文章,完全不用输入表也可以。实现方法是,读取当前进程的PEB,再读取它的LDR字段得到Kernel32的基址。之后读取Kernel32的输出表,这样就能拿到你需要的api函数了,包括那个LoadLibrary。
雪    币: 38
活跃值: (47)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
lyricC 2011-2-11 23:29
6
0
我自虐一下。你别介意
雪    币: 1259
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu 2011-2-12 11:24
7
0
call  @f
  @@:
  jmp  edx

jmp edx执行了两次吧?
另:
szExitProcess    byte  "szExitProcess", 0
雪    币: 134
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
夜凉如水 3 2011-2-14 13:47
8
0
RTCodeStart  equ  this  byte

                lpLoadLibrary        dd        ?
                OldData                db        8  dup  (?)
                lpDllName        db        260  dup  (?)
                GameEntryOffset        dd        ?
               
        RTCodeEntry  equ  this  byte
       
                ;;自定位
                call        @F
                @@:
                pop     ebx
                sub     ebx,offset @B
               
                lea        eax,lpDllName
                add        eax,ebx
                push        eax
                call        [ebx + lpLoadLibrary]
               
               
               
                lea        esi,OldData
                add        esi,ebx
                mov        edi,dword  ptr  [ebx + offset  GameEntryOffset]
               
                push        dword  ptr  [esi]
                pop        dword  ptr  [edi]
               
                push        dword  ptr  [esi+4]
                pop        dword  ptr  [edi+4]
               
                jmp        edi

RTCodeEnd    equ  this  byte
雪    币: 6991
活跃值: (1217)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
JoenChen 4 2011-2-28 20:02
9
0
我试验了很多次, 发现在Xp系统下这个获取不到的, 也许堆栈本来就是不能够获取吧! 但是如果我把代码copy在堆内存中, 或者远程插入其他进程的线程中却可以. 这个是为什么呢?
雪    币: 61
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
华山论壳 2011-3-1 22:37
10
0
Include JGetApiAddr.asm
这个东东发出来让我看看  你别以为DLL导出的函数都在DLL内  都什么年代了  还用汇编写代码
哪天让哥哥用VC给你写一个没有输出表的GUI程序 让你见识下什么叫精通C语言和汇编
雪    币: 266
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
邓韬 9 2011-3-8 18:48
11
0
百度一下“老罗的缤纷天地”
雪    币: 266
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
邓韬 9 2011-3-8 18:50
12
0
别太狂了,国内高手级人物没见过你这号的
游客
登录 | 注册 方可回帖
返回