//ExeMemory.h #ifndef _EXE_MEM_H_ #define _EXE_MEM_H_ #include <memory.h> #if defined(WIN32) && defined(_MSC_VER) #include <windows.h> #else #include <sys/mman.h> #endif typedef int (*ExeMemoyFun)(); typedef unsigned int size_t; //#define EXE_MEMORY_DEBUG class ExeMemory { public: ExeMemory() { m_pCode=NULL; m_size=0; } ExeMemory(size_t size) { NewMem(size); } ~ExeMemory() { DelMem(); } void NewMem(size_t size) { DelMem(); //size=4096; //4字节对齐 //unsigned int mv=size%sizeof(void*); //if (mv!=0) size+=sizeof(void*)-mv; #if defined(WIN32) && defined(_MSC_VER) m_pCode=VirtualAlloc(NULL,size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); MEMORY_BASIC_INFORMATION t; DWORD dwResult=VirtualQuery(m_pCode,&t,sizeof(MEMORY_BASIC_INFORMATION)); /* if (dwResult) { TRACE("dwResult:%d/n",dwResult); TRACE("BaseAddress:%d/n",t.BaseAddress); TRACE("AllocationBase:%d/n",t.AllocationBase); TRACE("AllocationProtect:%d/n",t.AllocationProtect); TRACE("RegionSize:%d/n",t.RegionSize); TRACE("State:%d/n",t.State); TRACE("Protect:%d/n",t.Protect); TRACE("Type:%d/n",t.Type); } */ #else m_pCode = mmap(0,size,PROT_READ|PROT_WRITE|PROT_EXEC,MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); #endif if (m_pCode) { m_size=size; #if defined(WIN32) && defined(_MSC_VER) ::FlushInstructionCache(::GetCurrentProcess(),m_pCode,m_size); #endif } } void DelMem() { if (m_pCode!=NULL) { #if defined(WIN32) && defined(_MSC_VER) VirtualFree(m_pCode,NULL,MEM_RELEASE); //在删除的时候,请勿带内存大小参数,否则兼容工具会检测到不兼容特性 #else munmap(m_pCode, m_size); #endif m_size=0; m_pCode=NULL; } } void zero(unsigned char c) { memset(m_pCode, c, m_size); } size_t Size() { return m_size; } operator unsigned int() { return (unsigned int)m_pCode; } operator bool() { return (m_pCode!=NULL); } operator void*() const { return m_pCode; } operator unsigned char*() const { return (unsigned char *)m_pCode; } operator char*() const { return (char *)m_pCode; } void CallSub(size_t offset=0) { ExeMemoyFun fun=(ExeMemoyFun)((unsigned char *)m_pCode+offset); fun(); } int CallFun(size_t offset=0) { ExeMemoyFun fun=(ExeMemoyFun)((unsigned char *)m_pCode+offset); return fun(); } void SetValue(unsigned int template_val, unsigned int val, unsigned char op=0xB8) { if ( m_pCode==NULL || template_val==0 ) return; unsigned char *ptr=(unsigned char *)m_pCode; for (unsigned int i=0;i<m_size-4;i++) { if ( ptr[i]==op ) //0xB8 MOV EAX, imm32 指令 { if ( *(unsigned int*)(ptr+i+1)==template_val ) { *(unsigned int*)(ptr+i+1)=val; } } } } bool CopyFunction(void *pTemplateFun) { unsigned char *ptr=(unsigned char *)pTemplateFun; while ( *ptr == 0xE9 ) { int add=*(int *)(ptr+1); ptr+=5; ptr+=add; pTemplateFun=(void *)ptr; } size_t i=0; //以CALL 为结束 while(1) //C2 C3 CB CA { if ( ptr[i]==0xC3 || ptr[i]==0xCB ) { i++; break; } else if ( ptr[i]==0xC2 ) { i+=3; break; } else if ( ptr[i]==0xCA ) { i+=5; break; } i++; } size_t size=i; NewMem(size); zero(0x90); if (m_pCode==NULL) return false; memcpy(m_pCode,pTemplateFun,size); #ifdef EXE_MEMORY_DEBUG dump(); #endif int offset=ptr-(unsigned char *)m_pCode; ptr=(unsigned char *)m_pCode; //跳转修改 for (i=0;i<size-4;i++) { if ( ptr[i]==0xE8 ) //0xE8 CALL NEAR imm32 指令 { *(int*)(ptr+i+1)+=offset; } } #ifdef EXE_MEMORY_DEBUG dump(); #endif return true; } #ifdef EXE_MEMORY_DEBUG void dump() { if(m_pCode == NULL) return ; unsigned char *ptr=(unsigned char *)m_pCode; TRACE("/r/n"); unsigned int i; for (i=0;i<m_size;i++) { TRACE("%02X ",ptr[i]); if (i%8==7) TRACE("/r/n"); } TRACE("/r/n"); } #else void dump(){}; #endif private: void *m_pCode; size_t m_size; }; #endif //(_EXE_MEM_H_)