移除dll並保持正常執行

2021-04-13 13:09:09 字數 3196 閱讀 9652

將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 ...