|| 您现在的位置: 天下无挂网 >> 外挂文章 >> 加密破解技术 >> 外挂文章正文
:: 用户登录 ::

 
:: 专 题 栏 目 ::
:: 最新热门 ::
  • 没有热门外挂文章
  • :: 相关文章 ::
  • SuperDD外挂脱壳示例

  • 传奇强力外挂脱壳破解

  • 游戏外挂破解演示

  • api函数暴力获得
    作者:不详 文章来源:不详 点击数: 更新时间:2005-8-21

    .386
    .model flat, stdcall
    option casemap:none
    include \masm32\include\windows.inc

    GetKernelBase   proto   :DWORD
    GetApiAddress   proto   :DWORD, :DWORD

    .data
    szMyMsg             db  "--=   暴力搜索内存空间获得 Api 的线性地址  =--", 13, 10, 13, 10,\
                            "请注意:", 13, 10,\
                            "* 本对话框的线性地址是通过暴力搜索得来 *", 13, 10, 13, 10,\
                            "老罗的缤纷天地",13, 10, "http://www.luocong.com/", 0
    szMyCaption         db  "老罗的病毒基础教程系列 by LC", 0
    aKernel32Base       dd  0
    szUser32            db  "user32.dll", 0
    szExitProcess       db  "ExitProcess", 0
    aExitProcess        dd  0
    szLoadLibraryA      db  "LoadLibraryA", 0
    aLoadLibraryA       dd  0
    szGetProcAddress    db  "GetProcAddress", 0
    aGetProcAddress     dd  0
    szMessageBoxA       db  "MessageBoxA", 0
    aMessageBoxA        dd  0

    .code
    main:    
        call delta
    delta:
        pop ebp
        sub ebp, offset delta

        ;获得 Kernel32.dll 的基地址:
        invoke GetKernelBase, [esp]
        mov aKernel32Base, eax

        ;获得 Kernel32.dll 中的所需的 Api 的线性地址:
        invoke GetApiAddress, aKernel32Base, addr szExitProcess
        mov aExitProcess, eax
        invoke GetApiAddress, aKernel32Base, addr szLoadLibraryA
        mov aLoadLibraryA, eax
        invoke GetApiAddress, aKernel32Base, addr szGetProcAddress
        mov aGetProcAddress, eax

        ;载入 User32.dll :
        push offset szUser32
        call [ebp + aLoadLibraryA]

        ;获得 User32.dll 中的 MessageBoxA 的线性地址:
        push offset szMessageBoxA
        push eax
        call [ebp + aGetProcAddress]
        mov aMessageBoxA, eax

        ;呵呵,千呼万唤始出来,高兴了吧??
        push MB_OK or MB_ICONINFORMATION
        push offset szMyCaption
        push offset szMyMsg
        push NULL
        call [ebp + aMessageBoxA]

        ;退出:
        push 0
        call [ebp + aExitProcess]


    ;**************************************************
    ;函数功能:查找 Kernel32.dll 的基地址
    ;**************************************************
    GetKernelBase   proc uses esi edi dwKernelRet:DWORD
        LOCAL dwReturn: DWORD

        mov edi, dwKernelRet                ; edi = 堆栈顶
        and edi, 0ffff0000h                 ; 用 AND 获得初始页
        .while TRUE
            .if word ptr [edi] == IMAGE_DOS_SIGNATURE       ; 等于“MZ”吗?
                mov esi, edi                                ; Yes, next...
                add esi, [esi + IMAGE_DOS_HEADER.e_lfanew]  ; 就是 esi + 3ch
                .if word ptr [esi] == IMAGE_NT_SIGNATURE    ; 等于“PE”吗?
                    mov dwReturn, edi                       ; Yes, we got it.
                    .break
                .endif
            .endif
            ;以下等同于sub edi, 010000h,即每次减少64k:
            dec edi
            xor di, di
            .break  .if edi < 070000000h    ; 基地址一般不可能小于70000000h
        .endw
        mov eax, dwReturn

        ret
    GetKernelBase   endp


    ;**********************************************************************
    ;函数功能:从内存中 Kernel32.dll 的导出表中获取某个 API 的入口地址
    ;**********************************************************************

    GetApiAddress   proc uses ecx ebx edx esi edi hModule:DWORD, szApiName:DWORD
        LOCAL dwReturn: DWORD
        LOCAL dwApiLength: DWORD

        mov dwReturn, 0

        ;计算 API 字符串的长度(带尾部的0)
        mov esi, szApiName
        mov edx, esi
    Continue_Searching_Null:
        cmp byte ptr [esi], 0           ; 是否为 Null-terminated char ?
        jz We_Got_The_Length            ; Yeah, we got it.  
        inc esi                         ; No, continue searching.
        jmp Continue_Searching_Null     ; searching.......
    We_Got_The_Length:
        inc esi                         ; 呵呵, 别忘了还有最后一个“0”的长度。
        sub esi, edx                    ; esi = API Name size
        mov dwApiLength, esi            ; dwApiLength = API Name size

        ;从 PE 文件头的数据目录获取输出表的地址
        mov esi, hModule
        add esi, [esi + 3ch]
        assume esi: ptr IMAGE_NT_HEADERS
        mov esi, [esi].OptionalHeader.DataDirectory.VirtualAddress
        add esi, hModule
        assume esi:ptr IMAGE_EXPORT_DIRECTORY 
        mov edi,szApiName   
       mov ecx,[esi].AddressOfNameOrdinals
       add ecx,hModule;取得AddressOfNameOrdinals数组的指针
       ;invoke RVAToFileMap,hModule,[esi].AddressOfNames
       mov ebx,[esi].AddressOfNames
        add ebx,hModule;取得AddressOfNames数组的指针,特要注意AddressOfNames为指向指针的指针数组(个人之见),且都为RVA
    Continue_look:
        mov eax,[ebx]   
       add eax,hModule
       push ebx
       mov ebx,eax     

        push edi
       push ecx
       mov ecx,dwApiLength;字符串的长度
    Continue:
       mov al,[edi]
       mov ah,[ebx]
       xor al,ah;字符串的比较
       jnz again
       dec ecx
       inc edi
       inc ebx
       jcxz found
       jmp  Continue
    again:   
       pop ecx
       pop edi
       pop ebx
        add ebx,4 ;ebx指向AddressOfNames名的数组,值为双字型,所以加4
        add ecx,2;ecx指向序数数组,值是字类型,所以加2
       jmp Continue_look
    found:
        pop ecx
       pop edi
       pop ebx
       
        mov ebx,ecx
        mov dx,[ebx] ;ebx指向序数数组,值是字类型
        movzx edx,dx;因此将其转换成双字
        mov ebx,[esi].AddressOfFunctions 
       add ebx,hModule;取得AddressOfFunctions的指针
       shl edx, 2:索引乘以4 (AddressOfFunctions 数组中每个元素都是4字节大小) 
        add edx,ebx;然后加上数组首地址
       mov eax,[edx];eax就是所要函数的RVA了
       add eax,hModule  
        ret
    GetApiAddress       endp
    end main

    外挂文章录入:admin    责任编辑:admin 
  • 上一篇外挂文章:

  • 下一篇外挂文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口

    点击申请点击申请点击申请点击申请点击申请点击申请
    点击申请点击申请点击申请点击申请点击申请点击申请点击申请

    版权所有 Copyright? 2004-2008 天下无挂科技网 网站维护:GHOST
    网站域名:http://www.watxwg.com
    客服邮箱:txwgwa@163.com
    客服电话:13810978321
    客服 Q Q:12439470