2014-09-13 77 views
3

我想要的是製作一個C++ dll文件,其中包含一箇中間函數鉤子,用於監視遊戲中的值是否更改(Plants Vs Zombies)。現在,當通過頭包括內聯彙編我的問題是,當該.dll是建立它給出了一個錯誤
:-1: error: [release/PVZ_lib.o] Error 1(PVZ_lib是cpp文件的名稱,其中我主要是)我使用Qt Creator的使用內聯彙編創建一個C++ dll

作爲我的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; 
} 

我已經試過formattin g像這樣的彙編程序。

__declspec(naked) void code(void){ 

    __asm{ 
     //assembler 
    } 
} 
這種格式

我得到如下:

warning: 'naked' attribute directive ignored [-Wattributes] and a few error: was not declared in this scope

注:我不熟悉的掛鉤或內嵌彙編。

是我用來創建此代碼:

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

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

+0

這是您的代碼中包含錯誤的最小可編譯示例嗎? – Quest 2014-09-13 16:11:35

+0

對於「大多數」平臺,GCC不允許「裸」。 'scanptr test'與'scanptr!= test'相同。如果這是GCC彙編,那麼你需要'-masm = intel'來使用intel語法。否則,您需要使用AT&T語法.. – Brandon 2014-09-13 17:17:33

+0

除了@brandon評論中的優點之外,如果您閱讀gcc的更詳細的[inline asm文檔](https://gcc.gnu.org/onlinedocs/gcc/ Extended-Asm.html),你會看到有多個像這樣的asm語句(而不是單個多行語句)是一個壞主意。此外,修改寄存器(如ecx)而不讓gcc知道(通過限制,clobbers等)是一個壞主意。我懷疑用asm跳這樣也會導致問題。 – 2014-09-13 23:08:13

回答

0

我建議你使用像cheatEngine工具來找到您要編譯掛鉤和使用Visual Studio C++的地址做這個。

#define SOME_OFFSET = 0x5560; 

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

    } 

} 

而且,當你正在測試你的代碼,看如何在跳躍與CheatEngine內存執行。