yvqvan 发表于 2011-9-22 00:13:57

【求助】根据小小思维的问道非战斗状态补血的CALL的问题

新手,望乞知道的,能指点一二。不胜感激

我根据小小思维关于问道辅助的教材中第一集关于《找非战斗使用物品(药)CALL》,自己分析了下。
0048589F    CC                   INT3
004858A0    56                   PUSH ESI
004858A1    8B7424 08      MOV ESI,DWORD PTR SS:
004858A5    56                  PUSH ESI
004858A6    68 D0CE8800   PUSH asktao.0088CED0                     ; ASCII "pos = %d"
004858AB    68 2C200000   PUSH 202C
004858B0    E8 7B011400   CALL asktao.005C5A30
004858B5    83C4 0C         ADD ESP,0C
004858B8    833D 144A9D00 0>CMP DWORD PTR DS:,0
004858BF    74 5C         JE SHORT asktao.0048591D
004858C1    8B0D 54469D00   MOV ECX,DWORD PTR DS:
004858C7    56            PUSH ESI

跟小小思维的教程中是一样的。
用论坛下载的代码注入器测试,是正确。于是我自己写了如下代码(VC):
DWORD dwProcId = 4148;
BOOL bRet = WinLib_RaiseProcPrivilegToDebug(GetCurrentProcess());
if ( !bRet )
{
        MessageBox("提权失败", "提示", MB_OK);
        return;
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
if ( hProc )
{
        __asm
        {
                push 67
                push 8965840                     // 0x0088CED0
                push 8236                           // 0x202C
                mov eax, 6052400            // 0x005C5A30
                call eax
                add esp, 12                        // 0x0c
        }

        CloseHandle(hProc);
}

当运行到mov eax, 6052400的时候,我写的程序就报错,自动退出。调试发现,调用mov eax, 6052400时,返回的错误代码为:0x5,就是拒绝访问的意思。
代码中,我直接在进程管理器中查看的进程的ID。

我想请教如下2个问题:
1. 我的代码,自己想不出哪有问题,为什么会出现上面的。
2. 我想请教代码注入器,是如何实现的?

小小思维 发表于 2011-9-22 08:34:59

C/C++内嵌汇编不需要转换成10进制的。 逗号注意全角与半角~

yvqvan 发表于 2011-9-22 10:58:53

谢谢小小思维的回答,我理解为什么出错了,我虽然打开了目标进程,但是汇编代码所涉及的地址,代码等,并不是在目标的地址空间中,而是在我本地进程的地址空间,如果直接调用,肯定就会出问题。代码修改后,调用依然没有效果。代码如下:
DWORD dwProcId = 556;

BOOL bRet = WinLib_RaiseProcPrivilegToDebug(GetCurrentProcess());
if ( !bRet )
{
        MessageBox("提权失败", "提示", MB_OK);
        return;
}

// 打开进程
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcId);
if ( hProc )
{
        // 分配空间
        LPVOID lpAddress = VirtualAllocEx(hProc, NULL, REMOTE_MEM_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if ( NULL == lpAddress )
        {
                MessageBox("分配虚拟地址失败", "提示", MB_OK);
                CloseHandle(hProc);
                return;
        }

        // 写入代码
        bRet = WriteProcessMemory(hProc, lpAddress, CallAddBlood, REMOTE_MEM_SIZE, NULL);
        if ( !bRet )
        {
                MessageBox("写入代码失败", "提示", MB_OK);
                VirtualFreeEx(hProc, lpAddress, REMOTE_MEM_SIZE, MEM_DECOMMIT | MEM_RESERVE);
                CloseHandle(hProc);
                return;
        }

        // 调用加血CALL
        DWORD dwRemoteThreadId = 0;
        HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)lpAddress, NULL, 0, &dwRemoteThreadId);
        if ( NULL == hRemoteThread )
        {
                MessageBox("执行远程代码失败", "提示", MB_OK);
        }
        else
        {
                WaitForSingleObject(hRemoteThread, NULL);
                CloseHandle(hRemoteThread);
        }

        VirtualFreeEx(hProc, lpAddress, REMOTE_MEM_SIZE, MEM_DECOMMIT | MEM_RESERVE);
        CloseHandle(hProc);
}
else
{
        DWORD dwErrorCode = GetLastError();
        OutputDebugString("OpenProcess Failed!\n");
}

yvqvan 发表于 2011-9-22 11:04:27

常量定义:
#define REMOTE_MEM_SIZE                0x6000

小小思维 发表于 2011-9-22 11:16:26

你用OD反汇编下你的程序看看,注意CALL的地方的汇编。创建了远程线程,你可以附加好游戏,看你创建的地址,是否写入正常CALL数据~~~

yvqvan 发表于 2011-9-22 14:09:18

调试发现,WriteProcessMemory写入的地址,数据不对,在起始地址偏移A93处,才出现正确的代码。
还没找为啥写入的时候,数据发生很大变化。

cooby 发表于 2013-9-28 14:12:59

顶你个肺啊,这不是骂人哦。辛苦了。

qq412158094 发表于 2019-3-28 15:40:06

支持楼主,支持看流星社区,以后我会经常来!
页: [1]
查看完整版本: 【求助】根据小小思维的问道非战斗状态补血的CALL的问题