const char* GetName()
{
std::string s = *(std::string*)(this + 0x28);
return s.c_str();
}
更新
struct Entity
{
static Entity* GetCurrentPlayer()
{
return (Entity*)(*(DWORD*)((DWORD)GetModuleHandleA("League of Legends.exe") + (DWORD)ADR_LocalPlayer));
}
}
UPDATE2:
实际上,我需要做的就像Cheat Engine一样:读取位于某个指针的字符串(this)+ Offset 0x28作为const char *返回,因为我需要此数据类型。
我也尝试用const char *直接访问地址,这给了我神秘的符号。顶部的示例正在崩溃游戏。
我想我需要另一种数据类型或其他方式来访问数据?!
注意:这是一个注入的DLL,我通过地址访问数据
答案 0 :(得分:1)
我认为这就是你需要的,将目标地址设置为Read,Write和Execute(如果你想改变代码)。
VirtualProtect的((LPVOID)的targetAddress,5,PAGE_EXECUTE_READWRITE,&安培; oldp);
这是一个完整的场景:
使用共享内存部分编写DLL。 DLL应链接到您的主应用程序以启用接收通知或数据(字符串),并在您需要控制远程进程时启用从主应用程序发送命令。
您的主应用程序应该创建远程线程,该线程中的代码将是将DLL加载到远程进程中,然后DLL应该从那里接管。
使用您选择的进程间通信机制,开始在远程进程和主应用程序之间发送/接收数据。
这是一个DLL注入功能(在你的主应用程序中),用于将你的DLL注入远程进程:
int Inject(char *fname,char *dllname,int NewProcess,DWORD PID) // 1=new process, 2= PID, 3=current process
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
BOOL rv;
void *pr;
HANDLE hh;
SIZE_T bwrit;
DWORD par,tid;HANDLE th;
FARPROC LoadLibProc = GetProcAddress(GetModuleHandleA("KERNEL32.dll"), "LoadLibraryA");
FARPROC ExitThreadProc = GetProcAddress(GetModuleHandleA("KERNEL32.dll"), "ExitThread");
char InjectedCode[500] =
{// 0xcc,
0x60, // pushad
0xB8, 00, 00, 00, 00, // mov EAX, 0h | Pointer to LoadLibraryA() (DWORD)
0xBB, 00, 00, 00, 00, // mov EBX, 0h | DLLName to inject (DWORD)
0x53, // push EBX
0xFF, 0xD0, // call EAX
0x5b, // pop EBX
0xB8, 00, 00, 00, 00, // EAX 2 mov EAX, 0h | Pointer to ExitThreadProc() (DWORD)
0x6a,00, // Push 00
0xFF, 0xD0, // call EAX
//0xcc // INT 3h
0x61, // popad
//0xcc
// 0xc3 // ret
};
int nob=30;
char *DLLName;
DWORD *EAX, *EBX, *EAX2;
DLLName = (char*)((DWORD)InjectedCode + nob);
strcpy( DLLName, dllname );
EAX = (DWORD*)( InjectedCode + 2);
EBX = (DWORD*) ( InjectedCode + 7);
EAX2 = (DWORD*)( InjectedCode + 16);
*EAX=(DWORD)LoadLibProc;
*EAX2=(DWORD)ExitThreadProc;
*EBX=nob;
ZeroMemory((VOID*)&si, sizeof(si));
si.dwFlags=STARTF_USESHOWWINDOW;//1
si.wShowWindow=SW_HIDE;//0
if (NewProcess==1) {
rv=CreateProcessA(fname,0,0,0,FALSE,CREATE_SUSPENDED,0,0,&si,&pi);
if (rv==FALSE) {return -1;}
hh=pi.hProcess;
}
TCHAR bb[200];
if (NewProcess==2) {////PROCESS_ALL_ACCESS
hh=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_WRITE|PROCESS_VM_OPERATION ,0,PID);
if (hh==NULL) return -6;
}
if (NewProcess==3) {
hh=GetCurrentProcess();
}
//if (hh==INVALID_HANDLE_VALUE) {printf("\nError Opening Process...");return;}
pr=VirtualAllocEx(hh,0,500,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (pr==NULL) return -7;
Sleep(100);
//printf("\nAddress Allocated=%x",pr);
*EBX+=(DWORD)pr;
rv=WriteProcessMemory(hh,pr,InjectedCode,500,&bwrit);
if (rv==0) return -8;
th=CreateRemoteThread(hh,NULL,0,(LPTHREAD_START_ROUTINE)pr,&par,0,&tid);
if (th==NULL) return -9;
return 0;
}
现在,对于DLL,在DLL CPP中,添加共享内存部分以保存用于进程间通信的数据:
#pragma data_seg("shared")
char whateverdatatoshare[16384]={0};
// you can also define events or variables to use to signal the remote process or the main app of any incoming data
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws") // This instructs the linker to make this section readable,writable and shared
在您的APIENTRY dllmain函数中,创建一个线程来执行您想要的任何操作,例如每秒读取您的字符串或数据以将其发送回主应用程序。
BOOL APIENTRY DllMain1( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DWORD par,tid;
HANDLE thandle;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
thandle= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&MsgThread,&par,0,&tid);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
你的线程代码应该执行嗅探你想要的字符串的实际工作。
非常重要:要确保您可以在内存中读/写,请使用:
首先将页面设置为PAGE_EXECUTE_READWRITE
**VirtualProtect((LPVOID)targetaddress,5,PAGE_EXECUTE_READWRITE,&oldp);**
第二:IsBadWritePtr或IsBadReadPtr,以确保您可以写或读。
答案 1 :(得分:0)
史蒂夫已经提到过,由于受到操作系统的保护,你无法访问其他应用程序的内存。您可以通过运行两个小程序来检查,第一个创建一个变量,将其指针存储在一个文件中并在此之后继续运行(通过等待用户输入或其他)。第二个程序从文件中读取指针,然后尝试使用其内容。不会工作。
此外,请查看GetModuleHandleA的文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms683199%28v=vs.85%29.aspx
它说:
"检索指定模块的模块句柄。该模块必须已由调用进程加载。"
和
"将名称与当前映射到调用进程的地址空间的模块的名称进行比较(大小写独立)。"
由于你想获得一个由另一个进程加载的模块,这也无法正常工作。