使用内联汇编创建c ++ dll

时间:2014-09-13 16:04:31

标签: c++ qt assembly dll hook

我想要的是制作一个带有mid函数钩子的c ++ dll文件,以观察游戏中的值何时发生变化(Plants Vs Zombies)。现在我的问题是当通过标题包含内联汇编时,当构建.dll时它会给出错误 :-1: error: [release/PVZ_lib.o] Error 1(PVZ_lib是我的主要文件所在的cpp文件的名称)

我使用QT Creator作为我的IDE使用MinGW 4.7编译器。

装配标题

#ifndef ASM_H
#define ASM_H
#include "addr.h"

DWORD scan      =0;
DWORD scanreg   =0;
DWORD scanptr;

void code(void){

    asm("ADD [EAX+0x5560],ECX");

    asm("MOV scanreg,ECX");

    asm("MOV ECX,[EAX+0x5560]");
    asm("CMP ECX,2706");
    asm("JLE SHORT PlantsVs.00430A9D");

    asm("jmp[scan]");


}

#endif // ASM_H

功能

#include "addr.h"    

void addr::PlaceJMP(BYTE *Address,DWORD jumpto,DWORD lenght){
    DWORD dwoldprotect, dwbkup, dwreladdr;

    VirtualProtect(Address,lenght,PAGE_EXECUTE_READWRITE,&dwoldprotect);
    dwreladdr = (DWORD) (jumpto -(DWORD)Address) - 5;
    *Address  = 0xE9l;
    *((DWORD*)(Address+0x1))= dwreladdr;

    for(DWORD x=0x5;x<lenght;x++){
        *(Address+x)=0x90;
    }

    VirtualProtect(Address,lenght,dwoldprotect,&dwbkup);
}

MODULEINFO addr::GetModuleInfo(char *name){
    MODULEINFO modinfo={0};
    HMODULE hModule =GetModuleHandle(name);
    if(hModule == 0){
        return modinfo;
    }

    GetModuleInformation(GetCurrentProcess(),hModule, &modinfo,sizeof(MODULEINFO));
    return modinfo;
}

DWORD addr::FindPat(char *module,char *pattern,char *mask){
    MODULEINFO mInfo = GetModuleInfo(module);
    DWORD base =(DWORD)mInfo.lpBaseOfDll;
    DWORD size =(DWORD)mInfo.SizeOfImage;
    DWORD i;
    bool found = true;
    DWORD PatternLenght = (DWORD)strlen(mask);
    for(i=0;i<size-PatternLenght;i++){

        for(DWORD j=0;j<PatternLenght;j++){
            found &=mask[j] == '?' || pattern[j] == *(char*)(base+i+j);
        }
    }
    if(found){
        return base+i;
    }
    return NULL;
}

主要

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include "addr.h"
#include "ASM.h"
addr stuff;

void initHooks(){

        DWORD find = stuff.FindPat("PlantsVsZombies.exe",
                                   "\x01\x88\x00\x00\x00\x00\x8B\x88\x00\x00\x00\x00\x81\xF9\x00\x00\x00\x00\x7E\x78",
                                   "xx????xx????xx????xx"
                                   );
    }

    DWORD WINAPI watch(){
        scanptr= scanreg;//+0x3C
        DWORD test=scanptr;

        for(;;Sleep(150)){
            if(scanptr!=test){
              test=scanptr;
                //addr.MsgBoxAddr(1);
            }
        }
    }

    BOOL WINAPI DLLMain(HINSTANCE hinstDLL,DWORD ftwReason,LPVOID lpReserved){
        initHooks();
        switch(ftwReason){
            case DLL_PROCESS_ATTACH:
            CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)watch(),NULL,NULL,NULL);
            break;
        }

    return TRUE;
}

我尝试过像这样格式化汇编程序。

__declspec(naked) void code(void){

    __asm{
         //assembler
    }
}

以这种格式我得到以下内容:

  

警告:&#39;裸体&#39;属性指令忽略[-Wattributes]和一些   错误:未在此范围内声明

注意:我不熟悉挂钩或内联装配。

我用来创建此代码的内容:

https://www.youtube.com/watch?v=A8PGxbu4EqQ

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

1 个答案:

答案 0 :(得分:0)

我建议您使用cheatEngine之类的工具来查找要挂钩的地址,并使用Visual Studio C ++编译器执行此操作。

#define SOME_OFFSET = 0x5560;

void __declspec(naked) _stdcall MyHack(){
   __asm{
     add [eax+SOME_OFFSET], ecx
     //other stuff...

  }

}

此外,无论何时测试代码,都要观察CheatEngine在内存中的跳转方式。