随笔-43  评论-2  文章-6  trackbacks-0
 
BOOL WINAPI change(HWND hwnd,LPCWSTR lpString)
{
    TCHAR 
*di[10= {_T("zero "), 
            _T(
"one "),
            _T(
"two "),
            _T(
"three "),
            _T(
"four "), 
            _T(
"five "), 
            _T(
"six "), 
            _T(
"seven "), 
            _T(
"eight "), 
            _T(
"nine ")}
;

    
int nLen = wcslen(lpString);

    wchar_t wcIndex;
    CString strOne;
    CString strSum 
= "";
    
    
for(int n = 0; n < nLen - 2; n++)
    
{
        
if (lpString[n] >='0' && lpString[n] <= '9')
        
{
           
 wcIndex = lpString[n];            
//int index = _wtoi(&lpString[n]);
            int index = _wtoi(&wcIndex);

            
//CString strIndex;
            
//strIndex.Format("%d",index);
            
//MessageBox(NULL,strIndex,"ooooo",0);

            strOne 
= di[index];
        }

        strSum 
= strSum + strOne;
    }

    
    
//Other Codes
}

上面代码中,红色部分:
CString对象可以当作数组使用,对象名可以当作数组名,利用“[]”定位其中的字符。
但注意:当对象名当作指针用时,其返回的是整个字符串,而不可以返回指定的某个字符。
posted @ 2012-12-25 13:25 寻步 阅读(941) | 评论 (0)编辑 收藏

无参Call:
打坐CALL

有参Call:
普通攻击CALL

走路CALL

技能CALL

捡物CALL

选怪CALL

喊话CALL

死亡回程CALL

posted @ 2012-12-24 20:12 寻步 阅读(706) | 评论 (0)编辑 收藏
数组在定义的同时可以被集体初始化,如下:
BYTE m_btNewBytes[6]= {0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3};

如果定义完后,再初始化,则只能一个元素一个元素地进行初始化,如下:
BYTE m_btNewBytes[6];
m_btNewBytes[0] = 0xE9;
m_btNewBytes[5] = 0xC3;

下面的这种写法是错误的。
BYTE m_btNewBytes[6];
m_btNewBytes[6]= {0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3};
posted @ 2012-12-24 16:55 寻步 阅读(212) | 评论 (0)编辑 收藏
1.同一个按钮,挂机和取消挂机是两种状态,应该有一个标志位做判断。这里,挂机的时候标志位为1,取消挂机时,标志位为0。
   用CE进行反复搜索,直到找到标志位的地址。
2.用OD挂接游戏,在标志位地址处下内存访问(写)断点,按挂机按钮断下。此处来到了外挂的代码领空,上下文就是相关的功能代码。
posted @ 2012-12-24 16:47 寻步 阅读(439) | 评论 (0)编辑 收藏
Windows消息分为队列消息和非队列消息,WH_GETMESSAGE不能取到非队列消息,用SendMessage发送的消息不经过队列,用PostMessage发送的消息被放入队列,
即,WH_GETMESSAGE Hook只拦截由GetMessage or PostMessage PeekMessage的队列消息。
posted @ 2012-12-24 15:17 寻步 阅读(2996) | 评论 (0)编辑 收藏
    DWORD addr = 0;

    __asm
{
        push eax
        mov eax,[ebp
+4h]
        mov addr,eax
        pop eax
    }


    CString strTemp;
    strTemp.Format(
"%x8",addr);
    MessageBoxA(NULL,strTemp,
"当前函数的返回地址",0);
posted @ 2012-12-14 13:31 寻步 阅读(560) | 评论 (0)编辑 收藏
1.函数名,可以代表函数的地址(常量)。
2.函数指针,指针变量,指向函数。
posted @ 2012-12-13 16:50 寻步 阅读(394) | 评论 (0)编辑 收藏
1.提升进程访问权限
bool EnableDebugPriv()
{
    HANDLE hToken;
    LUID seDebugNameValue;
    TOKEN_PRIVILEGES tkp;
    OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES
|TOKEN_QUERY,&hToken);
    LookupPrivilegeValue(NULL,SE_DEBUG_NAME,
&seDebugNameValue);

    tkp.PrivilegeCount 
= 1;
    tkp.Privileges[
0].Luid = seDebugNameValue;
    tkp.Privileges[
0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken,FALSE,
&tkp,sizeof(tkp),NULL,NULL);

    
return true;
}

2.根据进程名称得到ID,如果有多个运行实例,返回第一个枚举到的进程的ID
DWORD ProcessNameToId(LPCTSTR lpszProcessName)
{
    HANDLE hSnapShot 
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32 pe;
    pe.dwSize 
= sizeof(PROCESSENTRY32);
    Process32First(hSnapShot,
&pe);
    
do 
    
{
        
if (!strcmp(lpszProcessName,pe.szExeFile))
        
{
            
return pe.th32ProcessID;
        }

    }
 while (Process32Next(hSnapShot,&pe));
}


3.通过进程的PID得到进程的路径
CString  GetProcessFullPath(DWORD idProcess)
{
    CString str;
    
//得到进程句柄
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, idProcess);
    
if (NULL == hProcess)
    
return NULL;
    
//通过hProcess参数,得到指定进程的路径
    DWORD dw = GetModuleFileNameEx(hProcess,  
                                   NULL,       
                                  str.GetBuffer(MAX_PATH),    
                                  MAX_PATH);
    str.ReleaseBuffer();
    CloseHandle(hProcess);
    
return str;
}
 

4.通过PID得到进程调用的各个模块的全路径,显示在列表框
CString CModule::GetProcessModuleFullPath(DWORD PID)
{
    HMODULE hMod[
1024];
    
char szModName[MAX_PATH];
    
static TCHAR Buffer[MAX_PATH];
    
    HANDLE hProcess;
    DWORD cbNeed 
= 0;

    m_listmod.DeleteAllItems();
    hProcess 
= ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,PID);
    BOOL b 
= EnumProcessModules(hProcess, hMod, sizeof(hMod), &cbNeed);

    
if( hProcess == INVALID_HANDLE_VALUE && b == FALSE )
    
{
        CloseHandle( hProcess );
        
return NULL;
    }

    
for ( int i = 0; i <=(cbNeed / sizeof(HMODULE)); i++ )
    

        
if (GetModuleFileNameEx( hProcess, hMod[i], szModName,
            
sizeof(szModName)))
        
{
            m_listmod.InsertItem(
0,szModName);

            wsprintf(Buffer,
"0x%08x",hMod[i]);
            m_listmod.SetItemText(
0,1,Buffer);
        }

    }

    CloseHandle( hProcess );
    
return NULL;
}
 

5.通过点击,得到列表值


void OnClickProcessList()
{
    UpdateData(TRUE);
    
//获得行号
    int nItem = m_listpro.GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);
//通过行号得到进程名
    szFileName = m_listpro.GetItemText(nItem,0);
    
//通过行号得到PID
    szPID= m_listpro.GetItemText(nItem,1);
}

posted @ 2012-12-12 09:26 寻步 阅读(332) | 评论 (0)编辑 收藏

GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。

CString ::GetBuffer有两个重载版本:

LPTSTR GetBuffer( );LPTSTR GetBuffer(int nMinBufferLength);

在第二个版本中,当设定的长度小于原字符串长度时,nMinBufLength = nOldLen,该参数会被忽

略,不分配内存,指向原CString;当设定的长度大于原字符串本身的长度时就要重新分配(reallocate)一块比较大的空间出来。而调用第一个版本时,应如通过传入0来调用第二个版本一样。

是否需要在GetBufer后面调用ReleaseBuffer(),是根据你的后面的程序是否需要继续使用该字符串变量,并且是否动态改变其长度而定的。如果你GetBuffer以后程序自函数就退出,局部变量都不存在了,调用不调用ReleaseBuffer没什么意义了。

这是一个非常容易被用错的函数,主要可能是由于大家对它的功能不太了解。其实点破的话,也不是那么深奥。
    GetBuffer(int size)是用来返回一个你所指定大小可写内存的成员方法。它和被重载的操作符LPCTSTR还是有点本质区别的,LPCTSTR是直接返回一个只读内存的指针,而GetBuffer则是返回一个可以供调用者写入的内存,并且,你可以给定大小。下面是个简单的,但也是非常典型的例子:
    int readFile(CString& str, const CString& strPathName)
    {
        FILE* fp = fopen(strPathName, "r"); // 打开文件
        fseek(fp, 0, SEEK_END);
        int nLen = ftell(fp); // 获得文件长度
        fseek(fp, 0, SEEK_SET); // 重置读指针
        char* psz = str.GetBuffer(nLen);
        fread(psz, sizeof(char), nLen, fp); //读文件内容
        str.ReleaseBuffer(); //千万不能缺少
        fclose(fp);
    }
    上面的函数是GetBuffer函数最典型的用法了,其实它就相当于申请一块nLen大小的内存,只不过,这块内存是被引用在CString对象的内部而已,这是非常有效的一种用法,如果不直接用GetBuffer函数来申请的话,那么你必须用new操作符(或者malloc()函数)在CString的外部申请,然后再将申请的内存拷贝到CString对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。
    ReleaseBuffer函数是用来告诉CString对象,你的GetBuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 CString将不会知道它现在所包含的字符串的长度,所以在使用完GetBuffer之后,必须立即调用ReleaseBuffer函数重置 CString的内部属性,其实也就是头部信息。

 

补充一下:

GetBuffer说白了就两个功能:

1:就是将CString里面的内存交到外部一个来处理,外部可以直接修改它的内容。

2:重新修改CString的内存大小,这个数值不包含null结尾符。

另一个典型的用法:就是将CString里面的内容变为int或long型,需要先获取里面的内存指针。这样就可以先GetBuffer(内存大小)方便直接转换。

如果在外部修改了CString里面的内容,在重新使用CString之前,需调用ReleaseBuffer()也就是说,ReleaseBuffer不需要每次都调用。

MSDN原文:

If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CSimpleStringT member methods.

The buffer memory is automatically freed when the CSimpleStringT object is destroyed.

If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length to ReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.

posted @ 2012-12-12 09:13 寻步 阅读(285) | 评论 (0)编辑 收藏
 CString csText;
 csText.Format( _T( "Last Scan Time taken - %lf sec" ), dblPerf );
 ::SendMessage(m_StatusBar, SB_SETTEXT, (WPARAM)2, (LPARAM)csText.GetBuffer(csText.GetLength()));
posted @ 2012-12-11 17:00 寻步 阅读(194) | 评论 (0)编辑 收藏
仅列出标题
共5页: 1 2 3 4 5