將dll從程序模組列表中移除並保持正常執行

2021-04-19 22:07:49 字數 3271 閱讀 4406

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

}

C 將dll打包到程式中

有時候我們會使用第三方的庫,好多遊戲也是使用第三方庫,在沒有安裝第三方就會出錯。我們有乙個簡單的方法把dll庫打包程式中 如果我們把dll放到庫中,屬性為資源 我看到blqw把執行從程式找dll寫為 using system using system.collections.generic usin...

C 將dll打包到程式中

最近比較懶,加上內容也不多就懶得排版了,字放大了,看起來應該方便一點 直接進入主題 先來看乙個栗子,假設現在有乙個第三方dll namespace testlibrary1 testlibrary1.dll 在專案中引用,然後呼叫其中的方法test,將輸出aaabbbccc using system...

C 將dll打包到程式中

本文告訴大家如何把 dll 打包到程式中。很多時候的 軟體 在執行的時候需要包括很多 dll 或其他的檔案,這樣的軟體在給其他小夥伴,就需要做乙個壓縮包,或者用安裝軟體。這樣感覺不太好,所以本文告訴大家乙個方法,把所有的 dll 放在乙個檔案,於是把自己的軟體給小夥伴就只需要給他乙個程式 然後安裝,...