將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
#include
#include
#include
#pragma comment(lib, "psapi.lib")
#define __printf printf
void hidelibrary(hmodule hmodule, lpvoid pcallbackaddr, lpvoid lparam);
typedef struct
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)
moduleentry32 memoduleentry;
memoduleentry.dwsize = sizeof(moduleentry32);
if(!module32first(hmodssnap, &memoduleentry))
do while(module32next(hmodssnap, &memoduleentry));
closehandle(hmodssnap);
return true;
}//列舉指定程序的所有執行緒
dword winapi enumandsetthreadstate(lpvoid lparam)}}
}while (thread32next(hthreadsnap,&te32));
}closehandle( hthreadsnap );
return 0;
}dword winapi gotocallbackaddr(lpvoid lparam)
//那份dll的拷貝不需要了,釋放~
virtualfree(cbfunc->lpnewdllbase, 0, mem_decommit);
delete cbfunc;
return 0;
}dword winapi unloadlibrary(lpvoid lparam)
_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)
resumethread(hthread);
closehandle(hthread);
return true;
}void hidelibrary(hmodule hmodule, lpvoid pcallbackaddr, lpvoid lparam)
closehandle(hthread);
return;
}///
//example
//rundll32 unloadlibrary.dll,test
dword winapi testthread(lpvoid lparam)
dword winapi testthread02(lpvoid lparam)
hmodule hdll;
extern "c"
int test()
bool apientry dllmain( handle hmodule,
dword ul_reason_for_call,
lpvoid lpreserved
)break;
}return true;
}
移除dll並保持正常執行
將dll從程序模組列表中移除並保持正常執行,這玩意想想是挺簡單,n久前byshell就用了,簡單的思路就是給當前的dll記憶體映像做份拷貝,然後跳到那份拷貝的位址空間的 回頭free掉原來的dll,然後馬上用virtualalloc在原基址上申請塊同樣大小的空間,並將那份拷貝還原回去,再跳回去執行。...
將dll從程序模組列表中移除並保持正常執行
將dll從程序模組列表中移除並保持正常執行,這玩意想想是挺簡單,n久前byshell就用了,簡單的思路就是給當前的dll記憶體映像做份拷貝,然後跳到那份拷貝的位址空間的 回頭free掉原來的dll,然後馬上用virtualalloc在原基址上申請塊同樣大小的空間,並將那份拷貝還原回去,再跳回去執行。...
docker 移除掉執行不正常的container
本菜鳥在剛學習docker的時候遇到了這樣的問題,記錄一下,當啟動乙個container的時候,docker ps 看到剛啟動的容器有問題,需要先docker stop然後在docker rm 掉。當然 啟動不成功也是因為沒有許可權,docker 容器無許可權 新增 privileged true ...