高手们进来看下。。。。。。反NP。。。。

社区服务
高级搜索
猴岛论坛综合游戏交流高手们进来看下。。。。。。反NP。。。。
发帖 回复
倒序阅读 最近浏览的帖子最近浏览的版块
13个回复

高手们进来看下。。。。。。反NP。。。。

楼层直达
cht562

ZxID:1676219

等级: 上等兵
举报 只看楼主 使用道具 楼主   发表于: 2009-05-01 0
游戏通过检测DLL, EXE,或是外挂窗口 封号的话,这个方法最好不过了。

可以绕过检测。

但是本人研究的外挂还没完成,还用不到这个,暂时没测试,有能力的可以测试下。



将dll从进程模块列表中移除并保持正常运行,这玩意想想是挺简单,n久前byshell就用了,

简单的思路就是给当前的dll内存映像做份拷贝,然后跳到那份拷贝的地址空间的代码,回头free掉原来的dll,

然后马上用VirtualAlloc在原基址上申请块同样大小的空间,并将那份拷贝还原回去,再跳回去执行。完。

代码写完后再实际程序中应用后发现问题,一旦调用到malloc或new的话就会崩溃,
于是去看了下byshell的代码,发现他申请内存是用VirtualAlloc,但是我大量的代码都是用new来分配,而且类对象不好用VirtualAlloc来分配吧~

经调式才清楚,原来每个dll,windows都会给其分配一个heap,
在freelibrary时系统会将其完全destroy掉,不怕你内存泄露。

调试时在FreeLibrary后HeapDestroy断点正好触发一次,就是这一次那个heap给销毁了。

解决办法就是在FreeLibrary前修改HeapDestroy的第一条指令为return,FreeLibrary后再修复。

实践证明,稳定......

*/


#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>

#pragma comment(lib, "Psapi.lib")

#define __printf printf

void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam);

typedef struct
{
HMODULE lpDllBase;
LPVOID lpNewDllBase;
PTHREAD_START_ROUTINE pAddress;
LPVOID lParam;
}UNLOADLIB_CALLBACK, *PUNLOADLIB_CALLBACK;

typedef
LPVOID WINAPI VIRTUALALLOC(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);

typedef
BOOL WINAPI VIRTUALFREE(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD dwFreeType
);


typedef
BOOL WINAPI HEAPDESTROY(
HANDLE hHeap
);

typedef
HMODULE WINAPI LOADLIBRARY(
LPCTSTR lpFileName
);

typedef
HANDLE WINAPI CREATETHREAD(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);

typedef void * __cdecl MEMCPY(void *, const void *, size_t);


BOOL incLibraryCount(HMODULE hMe)
{
//FreeLibrary后很多系统dll也会free掉,所以将所有已加载的再load一次以增加计数

HANDLE hModsSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);

if(INVALID_HANDLE_VALUE == hModsSnap)
{
return FALSE;
}

MODULEENTRY32 meModuleEntry;
meModuleEntry.dwSize = sizeof(MODULEENTRY32);

if(!Module32First(hModsSnap, &meModuleEntry))
{
CloseHandle(hModsSnap);
return FALSE;
}
do
{
if(LoadLibrary(meModuleEntry.szModule) == hMe)
FreeLibrary(hMe);

} while(Module32Next(hModsSnap, &meModuleEntry));

CloseHandle(hModsSnap);

return TRUE;
}

//枚举指定进程的所有线程
DWORD WINAPI EnumAndSetThreadState(LPVOID lParam)
{
HANDLE hThreadSnap = NULL;
THREADENTRY32 te32;
memset(&te32,0,sizeof(te32));
te32.dwSize = sizeof(THREADENTRY32);
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);

DWORD myThreadId = GetCurrentThreadId();
DWORD pid = GetCurrentProcessId();

if (Thread32First(hThreadSnap, &te32))
{
do
{
if (pid == te32.th32OwnerProcessID)
{
if(myThreadId != te32.th32ThreadID)
{
HANDLE hThread = OpenThread(
THREAD_SUSPEND_RESUME,
FALSE,
te32.th32ThreadID);

if(hThread != NULL)
{
if((int)lParam)
ResumeThread(hThread);
else
SuspendThread(hThread);

CloseHandle(hThread);
}
}
}
}
while (Thread32Next(hThreadSnap,&te32));
}
CloseHandle( hThreadSnap );

return 0;
}

DWORD WINAPI GotoCallBackAddr(LPVOID lParam)
{
PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

DWORD dwThreadId;
HANDLE hThread;

if(cbFunc->pAddress)
{
hThread = CreateThread(
NULL,
0,
cbFunc->pAddress,
cbFunc->lParam,
0,
&dwThreadId);

if(hThread)
CloseHandle(hThread);
}

//那份dll的拷贝不需要了,释放~
VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
delete cbFunc;

return 0;
}

DWORD WINAPI UnLoadLibrary(LPVOID lParam)
{
//__asm INT 3
__printf("UnLoadLibrary Entry.\r\n");

BYTE HeapDestroy_HookCode_bak[4];
BYTE HeapDestroy_HookCode[4] = "\xC2\x04\x00";//RETN 0004
MODULEINFO modinfo;
DWORD oldProtect;

PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

HMODULE hDllInstance = cbFunc->lpDllBase;
char dllpath_bak[MAX_PATH];

GetModuleFileName(hDllInstance, dllpath_bak, sizeof(dllpath_bak));
GetModuleInformation(GetCurrentProcess(), hDllInstance, &modinfo, sizeof(MODULEINFO));

//给所有dll(除了自己)增加计数,防止FreeLibrary的时候那些dll给系统卸载掉
incLibraryCount(hDllInstance);

//保险起见,挂起其他线程,搞定后再恢复
EnumAndSetThreadState((LPVOID)FALSE);

//FreeLibrary之后原来存放api地址的内存也会被释放,
//但是FreeLibrary之后还有些动作,趁现在还没free,关键API记下来
VIRTUALALLOC *_VirtualAlloc = (VIRTUALALLOC*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "VirtualAlloc");
LOADLIBRARY *_LoadLibrary = (LOADLIBRARY*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
CREATETHREAD *_CreateThread = (CREATETHREAD*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateThread");
MEMCPY *_memcpy = (MEMCPY*)
GetProcAddress(GetModuleHandle("ntdll.dll"), "memcpy");

//这个很关键,并不是我要调用,是 FreeLibrary 时系统会调用,我要hook它,
//不能给系统破坏这个heap,否则之后的dll貌似能工作,
//但却不能用new或malloc申请内存, VirtualAlloc可以代替之,
//但如果改写好多代码是划不来的,况且一些代码不好改,如list<T>的push内部的new

HEAPDESTROY *_HeapDestroy = (HEAPDESTROY*)
GetProcAddress(GetModuleHandle("kernel32.dll"), "HeapDestroy");

VirtualProtect(_HeapDestroy, 3, PAGE_EXECUTE_READWRITE, &oldProtect);

//修改第一条指令为直接返回
_memcpy(HeapDestroy_HookCode_bak, _HeapDestroy, 3);
_memcpy(_HeapDestroy, HeapDestroy_HookCode, 3);


//Sleep(100);
//终于到这里了~~~^_^!
FreeLibrary(hDllInstance);//释放

//修复刚hook的函数
_memcpy(_HeapDestroy, HeapDestroy_HookCode_bak, 3);
//_memcpy(_RtlFreeHeap, RtlFreeHeap_HookCode_bak, 3);

//在原来的dll基址申请同样大小的内存,并把之前的那份dll拷贝还原回去
if(_VirtualAlloc(hDllInstance,
modinfo.SizeOfImage,
MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE) == NULL
)
{
//失败,加载原来dll, 以正常方式工作
//注意,不宜在dllmain中调用HideLibrary,LoadLibrary将导致dllmain再次被调用,导致死循环啦
HMODULE hDll = _LoadLibrary(dllpath_bak);

//重新计算回调函数在hDll地址空间的地址
cbFunc->pAddress = (LPTHREAD_START_ROUTINE)
((DWORD)cbFunc->pAddress - (DWORD)hDllInstance + (DWORD)hDll);

LPTHREAD_START_ROUTINE pFunc1 = (LPTHREAD_START_ROUTINE)
((DWORD)EnumAndSetThreadState - (DWORD)hDllInstance + (DWORD)hDll);

//恢复被挂起的线程
_CreateThread(0, 0, pFunc1, (LPVOID)TRUE, 0, 0);

//调用回调函数
if(cbFunc->pAddress)
_CreateThread(0, 0, cbFunc->pAddress, cbFunc->lParam, 0, 0);

return 0;
}

_memcpy(hDllInstance, cbFunc->lpNewDllBase, modinfo.SizeOfImage);

//恢复被挂起的线程
EnumAndSetThreadState((LPVOID)TRUE);

//跳回原dll地址空间的GotoCallBackAddr,由它来释放这边VirtualAlloc申请的指针
_CreateThread(0, 0, GotoCallBackAddr, cbFunc, 0, 0);

return 0;
}

DWORD WINAPI HideLibrary02(LPVOID lParam)
{
//__asm INT 3
__printf("HideLibrary02 Entry.\r\n");

PUNLOADLIB_CALLBACK cbFunc = (PUNLOADLIB_CALLBACK)lParam;

MODULEINFO modinfo;

GetModuleInformation(GetCurrentProcess(), cbFunc->lpDllBase, &modinfo, sizeof(MODULEINFO));

//申请一块和当前dll同样大小的内存
cbFunc->lpNewDllBase = VirtualAlloc(NULL, modinfo.SizeOfImage, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if(cbFunc->lpNewDllBase == NULL)
return FALSE;

//给当前dll做份拷贝,复制所有数据到刚申请的内存,
memcpy(cbFunc->lpNewDllBase, modinfo.lpBaseOfDll, modinfo.SizeOfImage);

//计算在copy中UnLoadLibrary的地址,并另起线程到该地址执行
void *pNewUnLoadLibrary = LPVOID((DWORD)cbFunc->lpNewDllBase + (DWORD)UnLoadLibrary - (DWORD)modinfo.lpBaseOfDll);

DWORD ThreadId;
HANDLE hThread = CreateThread(0,0,
(LPTHREAD_START_ROUTINE)pNewUnLoadLibrary, (LPVOID)cbFunc, CREATE_SUSPENDED, &ThreadId);

if(hThread == NULL)
{
VirtualFree(cbFunc->lpNewDllBase, 0, MEM_DECOMMIT);
delete cbFunc;

return FALSE;
}

ResumeThread(hThread);
CloseHandle(hThread);

return TRUE;
}


void HideLibrary(HMODULE hModule, LPVOID pCallBackAddr, LPVOID lParam)
{
__printf("HideLibrary Entry.\r\n");

PUNLOADLIB_CALLBACK lparam = new UNLOADLIB_CALLBACK;

lparam->lpDllBase = hModule;
lparam->lpNewDllBase = NULL;
lparam->pAddress = (PTHREAD_START_ROUTINE)pCallBackAddr;
lparam->lParam = lParam;

HANDLE hThread = CreateThread(0,0,
HideLibrary02, (LPVOID)lparam, 0, NULL);

if(hThread == NULL)
{
__printf("CreateThread HideLibrary02 Failed.\r\n");

delete lparam;
return;
}

CloseHandle(hThread);

return;
}

///////////////////////////////////////////////////////////
//example
//rundll32 UnloadLibrary.dll,Test

DWORD WINAPI testThread(LPVOID lParam)
{
char *ptest = new char[512];

sprintf(ptest, "My Pid: %d\r\n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId());

MessageBox(0, ptest, (char*)lParam, 0);

delete ptest;

return 0;
}


DWORD WINAPI testThread02(LPVOID lParam)
{

HMODULE hModule = (HMODULE)lParam;


char *ptest = new char[512];

sprintf(ptest, "testThread02\r\n");

Sleep(500);

MessageBox(0, ptest, "start", 0);

//不设置回调函数,成功还好,一旦失败则gameover
HideLibrary(hModule, 0, 0);

sprintf(ptest, "My Pid: %d\r\n 用一些软件查看下,找不到这个dll吧?", GetCurrentProcessId());
MessageBox(0, ptest, "ok", 0);


delete ptest;

return 0;
}

HMODULE hDll;
extern "C"
{
__declspec(dllexport) int Test();
}

int Test()
{
//1
//主要线程开始工作后再HideLibrary不是很安全
//CreateThread(0, 0, testThread02, hDll, 0, 0);
//
//2
//free掉dll后再开启主要工作线程妥当些
char *p = strdup("hello");
HideLibrary(hDll, testThread, p);

Sleep(60000);

return 0;
}


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hDll = (HMODULE)hModule;

}
break;

}

return TRUE;
}


在DLL内建立窗体对游戏操作,EXE成为截体。EXE注入后自动退出,这样游戏没办法检测DLL和EXE了, 有些人可能不明白我的意思,,
我使用的是DLL注入方式,线程方式必须有个EXE,当然你可以通过很多方法来隐藏自己的EXE,这样的方法有很多,包括驱动的。但你们不觉得不过是个外挂还要动驱动,大材小用。简直是浪费,而且部分网吧是禁用驱动的,还有大部分人不精通编程,根本不理解驱动,现在我展示的是把自己,也就是DLL注入到进程后使DLL从列表模块中移出来,但我们的DLL依然在运行,这样,游戏检测进程内部的DLL就不会有我们的DLL名字存在。就是这样饶过检测的。



大牛们测试下。。看看行不行。。
xhy1121

ZxID:5917006

等级: 列兵
举报 只看该作者 沙发   发表于: 2009-05-01 0
汗.................狂汗
tt279

ZxID:1230248

等级: 下士
举报 只看该作者 板凳   发表于: 2009-05-01 0
顶!!!!!!!!!!!!!!!!!!!!!!!
tt279

ZxID:1230248

等级: 下士
举报 只看该作者 地板   发表于: 2009-05-01 0
!!!!!!!!!!!!!!!!!!!!!!!
150607243

ZxID:5902551

等级: 新兵
举报 只看该作者 4楼  发表于: 2009-05-01 0
哇靠,我没语言了.高手请来翻译成人类语言
tianwd3000

ZxID:6227396

等级: 新兵
举报 只看该作者 5楼  发表于: 2009-05-01 0
人才~~
xuchuanqi

ZxID:1950556

等级: 上等兵
举报 只看该作者 6楼  发表于: 2009-05-01 0
我耍刀的.高手
zhangyaomm

ZxID:6150559

等级: 新兵
举报 只看该作者 7楼  发表于: 2009-05-01 0
不懂头大!有党员不?、    
kksa123

ZxID:1995028

等级: 列兵
举报 只看该作者 8楼  发表于: 2009-05-01 0
确实 可以的。。貌似DLL注入方式~~很像写木马的方式。哈哈。
ac928

ZxID:5811573

等级: 列兵
举报 只看该作者 9楼  发表于: 2009-05-01 0
看不懂啊 
sq770

ZxID:6187190

等级: 新兵
举报 只看该作者 10楼  发表于: 2009-05-01 0
写了这么多。。值得表扬。。。刷刀闪人
cht562

ZxID:1676219

等级: 上等兵
举报 只看该作者 11楼  发表于: 2009-05-01 0
就是从木马程序那想到。。
8楼的看出来了嘛 
tangpc512

ZxID:1755440

等级: 上等兵
举报 只看该作者 12楼  发表于: 2009-05-01 0
耍刀就可以了...这个太.....
xiaoxiaion66

ZxID:6224780

等级: 新兵
举报 只看该作者 13楼  发表于: 2009-05-01 0
神呢來得
« 返回列表
发帖 回复