木感想

常常思索 没有结果 来来去去 依稀记得

导航

299错误解决记录

ReadProcessMemory一直报错。发晕了一整天。

GetLastError() Error:0299 = 仅完成部分 ReadProcessMemory 或 WriteProcessMemory 请求。

以为是OpenProcess的参数问题,不断的修改参数,程序成了这样子:

 hProcess = OpenProcess( //PROCESS_VM_OPERATION|PROCESS_VM_READ,
                                     PROCESS_ALL_ACCESS,
                                    //PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ,
                                    //PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,
                                    //PROCESS_QUERY_INFORMATION,
                                    FALSE,
                                    dwProcessId);
很惨那,都试遍了,还是依然不断的报299错误,也就是说:操作不了内存。

找不到头绪,就整理GetLastError(),作了一个函数,根据ErrorCode返回错误内容。这花费了2个多小时吧,因为顺便将一些最近新写的独立函数也做到模块中。

晚上吃了饭继续整理,体力吃不消啊,从早上6点已经干了12个小时了。其中ReadProcessMemory已经可以读自己的Process内容,但读其他Process依然返回0.

9点了,突然找到了一丝灵感,也许可以修改内存属性?

使用VirtualProtectEx修改内存,如下这样作:

     DWORD dwOldProt, dwNewProt = 0;
     VirtualProtectEx(hProcess, (void*) pAddress, dwRead, PAGE_READWRITE, &dwOldProt);

     if(!ReadProcessMemory( hProcess,
                                         (LPCVOID)pAddress,
                                         pRead,
                                         dwRead,
                                         &dwReaded))
     {

            char sState[260];
            DWORD dwError = GetLastError();
            sprintf(sState, "ReadProcessMemory failure! Error Code:%d\n\n%s \n\nSize:%d Readed:%d\n", 
                                 dwError,
                                 getLastErrorString(dwError), 
                                 dwRead,
                                 dwReaded);

            MessageBox(sState, "Query", MB_OK|MB_ICONWARNING);
            free(pRead);
            CloseHandle(hProcess);
            return FALSE;
     }

     VirtualProtectEx(hProcess, (void*) pAddress, dwRead, dwOldProt, &dwNewProt);

如此这般折腾后,居然可以读了,哇塞,我太开心了。

今晚可以好好休息一下,明天深入下去,将WriteProcessMemory也做好。形成一个完整的Read/Write工作过程。

 

-------------------------------------------------------------------------------------------------------

 

 

今天一直在分析读取结果,前面已经将数据读入到BYTE数组中,将数组内容和整数比较我考虑过多了,本来认为数据应该是由高到低依次排列,就写了下面的处理函数:
static long g_lSearchPosition = 0;
static long g_lTargetLength = 0;
static bool g_bSearchLock = false;
BOOL CQueryDlg::SearchIntBegin(BYTE* pTarget, long lTargetSize, int nVal)
{
 if(g_bSearchLock) return FALSE;

 g_lSearchPosition = 0;
 g_lTargetLength = lTargetSize;
 g_bSearchLock = true;

 return TRUE;
}

long CQueryDlg::SearchIntNext(BYTE* pTarget, int nVal)
{
 for(int i=g_lSearchPosition; i<g_lTargetLength-3; i++, g_lSearchPosition++)
 {
  int iRead = pTarget[i]<<24 | pTarget[i+1]<<16 | pTarget[i+2]<<8 | pTarget[i+3];
  if(iRead == nVal)
  {
   g_lSearchPosition = i+1;
   if(i>=(g_lTargetLength-3)) g_bSearchLock = false;
   return i;
  }
 }

 g_bSearchLock = false;

 return -1;
}
但是比较结果一直找不到所需要的结果。找到的大量结果都不是正确的地址。
难道是内存中数据存储格式的问题?于是修改iRead组合方式:
int iVal = ((pRead[i]<<24) | (pRead[i+1]<<16) | (pRead[i+2]<<8) | (pRead[i+3]));
int iVal = ((pRead[i]<<0) | (pRead[i+1]<<8) | (pRead[i+2]<<16) | (pRead[i+3]<<24));
int iVal = MAKELONG( MAKEWORD(pRead[i], pRead[i+1]),MAKEWORD(pRead[i+2], pRead[i+3]));
... ...
依然没有找到正确的地址。
今天早上起来,问题现在已经集中在ReadProcessMemory上。一定是调用这个函数的时候出现了问题。
重新修改这个函数的处理过程,以整数为基础,作出如下程序:
#define HOS_READLEN 4096

DWORD dwReaded = 0;
long lPtr = PtrToLong(mbi.BaseAddress);
long lEnd = PtrToLong(mbi.BaseAddress) + (long)mbi.RegionSize;

int iVal[HOS_READLEN];
while( lPtr<lEnd )
{
 memset(iVal, 0, sizeof(int)*HOS_READLEN);
 ReadProcessMemory(hProcess, LongToPtr(lPtr), iVal, sizeof(int)*HOS_READLEN, &dwReaded);

 for(int i=0; i<HOS_READLEN; i++)
 {
  if(iVal[i] == nVal)
  {
   char sState[260];
   sprintf(sState, "Find Result %d at:0x%8.8X %d\n", nVal, lPtr, dwReaded);
   TRACE0(sState);
  }
 }
 lPtr+=sizeof(int)*HOS_READLEN;
}
终于找到了想要的结果,看起来以整数Read不仅快速而且判读很容易。
以后要是再读什么的话,直接将读取的内容做成块,以块的方式操作。那么ReadProcessMemory会在执行操作的时候按照数据块的大小运行,难怪有些人会设计一个CProcessRead类,这么小的功能做成类,以后就不灵会了,空洞而且无聊哟。

经过GetTickCount()测试我发现HOS_READLEN定义成不同的长度,运行速度差别很大。
HOS_READLEN TickCount
4096                   109
1024                   125
256                     296
128                     516
64                       687
32                       1219
16                       2297
8                         4468
4                         9032
2                         17968
1                         35485


WriteProcessMemory没遇到问题,一次试验就有了结果。
下来我想看看Heap处理过程,对Heap数据进行过滤。


posted on 2008-09-21 22:04  跌跌撞撞  阅读(5581)  评论(0编辑  收藏  举报