我想要的是製作一個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
這是您的代碼中包含錯誤的最小可編譯示例嗎? – Quest 2014-09-13 16:11:35
對於「大多數」平臺,GCC不允許「裸」。 'scanptr test'與'scanptr!= test'相同。如果這是GCC彙編,那麼你需要'-masm = intel'來使用intel語法。否則,您需要使用AT&T語法.. –
Brandon
2014-09-13 17:17:33
除了@brandon評論中的優點之外,如果您閱讀gcc的更詳細的[inline asm文檔](https://gcc.gnu.org/onlinedocs/gcc/ Extended-Asm.html),你會看到有多個像這樣的asm語句(而不是單個多行語句)是一個壞主意。此外,修改寄存器(如ecx)而不讓gcc知道(通過限制,clobbers等)是一個壞主意。我懷疑用asm跳這樣也會導致問題。 – 2014-09-13 23:08:13