1. 程式人生 > >DLL與Shellcode完全解除安裝自身

DLL與Shellcode完全解除安裝自身

原創文章,轉載請貼出處

遠端注入時有一個不痛不癢的問題,DLLshellcode如何解除安裝自身,做到無痕清除?

由於我的DLL自解除安裝用到了Shellcode,所以兩個問題都需要解決。

DLL解除安裝一般使用FreeLibrary,但是如果DLL自己Free自己,會遇到下一條指令(eip/rip)無效的問題(DLL自己的記憶體空間已經解除安裝了,而下一條指令仍然指向原來的DLL空間)。微軟給出的解決辦法是FreeLibraryAndExitThread這個函式,解除安裝DLL後立馬退出。

FreeLibrary只是把DLL的引用計數減1,如果之前多次LoadLibrary,則需要多次FreeLibrary來完全解除安裝

DLL,而FreeLibraryAndExitThread只是呼叫一次FreeLibrary就退出了,很可能DLL根本沒有被解除安裝。

DLL外部,以下程式碼可以完全解除安裝DLL

        while(ret)

         {

                   ret= FreeLibrary(hmod);

         }

但是不能在DLL內部使用。

於是想到可以通過把釋放DLL的程式碼寫成Shellcode,這樣即使DLL被解除安裝也不會使eip無效。

通過GlobalAlloc得到緩衝區(不能用malloc,因為它的記憶體隨DLL一同釋放了),用VirtualProtect使緩衝區可執行,

memcpy複製真正釋放dll的程式碼到緩衝區中,執行程式碼,就可以完全解除安裝DLLX86程式碼如下)

一點要注意,我的上一篇文章提到VC需要關閉幾個開關才能正常的拷貝函式記憶體指令

struct myEnvir

{

         ptGetProcAddress GetProcAddress;

         ptFreeLibrary FreeLibrary;

         ptExitThread ExitThread;

         ptGlobalFree GlobalFree;

} ;

long__stdcall  DoTrulyUnloadDLLAndExitThread(myEnvir* par,HMODULE hmod,DWORD exitcode,void

* pcode)

{

         BOOL ret=1;

        //ptFreeLibrary PFreeLibrary=(ptFreeLibrary)par->GetProcAddress(par->hmodkernel,par->pfree);

        // PExitThread=(ptExitThread)par->GetProcAddress(par->hmodkernel,par->pexit);

        while(ret)

         {

                   ret=par->FreeLibrary(hmod);

         }

        void* pExit=par->ExitThread;

        void* pFree=par->GlobalFree;

        __asm{

                   push exitcode

                   push 0

                   push pcode

                   push pExit

                   jmp pFree

         }

        return 0;

}

void__stdcall TrulyUnloadDLLAndExitThread(HMODULE hmod,DWORD exitcode)

{

        void* p=(BYTE*)GlobalAlloc(GMEM_FIXED,200);

         memcpy(p,DoTrulyUnloadDLLAndExitThread,200);

         DWORD oldpro;

         VirtualProtect(p,100,PAGE_EXECUTE_READWRITE,&oldpro);   

        typedef long (__stdcall *ptFun)(myEnvir* par,HMODULE hmod,DWORD exitcode,void* pcode);

         ptFun pFun=(ptFun)p;

         myEnvir par={GetProcAddress,FreeLibrary,ExitThread,GlobalFree};

         pFun(&par,hmod,exitcode,p);

}

要注意所有的API函式地址都被重定位過了,所以我們的shellcode需要呼叫者提供幾個API函式的地址(見結構體myEnvir

Shellcode仍然需要解除安裝自己,因為它是由GlobalAlloc分配的,如果這樣結束的話就會造成記憶體洩漏。於是使用了一些堆疊技巧

        __asm{

                   push exitcode

                   push 0

                   push pcode

                   push pExit

                   jmp pFree

         }

Call一個函式會把返回地址push入堆疊,我們自己把exitthread的地址push入堆疊,作為返回地址,然後呼叫GlobalFree,由於free掉了shellcode後直接到了exitthread,所以不會造成錯誤。

x64環境下大同小異,只是呼叫ExitThreadGlobalFree時用rcx傳引數,而且彙編程式碼需要用shellcode完成

X64程式碼:

struct myEnvir

{

         ptGetProcAddress GetProcAddress;

         ptFreeLibrary FreeLibrary;

         ptExitThread ExitThread;

         ptGlobalFree GlobalFree;

} ;

long__stdcall  DoTrulyUnloadDLLAndExitThread(myEnvir* par,HMODULE hmod,DWORD exitcode,void* pcode)

{

         BOOL ret=1;

        //ptFreeLibrary PFreeLibrary=(ptFreeLibrary)par->GetProcAddress(par->hmodkernel,par->pfree);

        // PExitThread=(ptExitThread)par->GetProcAddress(par->hmodkernel,par->pexit);

        while(ret)

         {

                   ret=par->FreeLibrary(hmod);

         }

        //par->ExitThread(exitcode);

        typedef void (*ptShellcode)(void* pcode,void* pexit,void* pfree);

         ptShellcode pFun=(ptShellcode)((char*)pcode+200);

         pFun(pcode,par->ExitThread,par->GlobalFree);

        /*void* pExit=par->ExitThread;

         void* pFree=par->GlobalFree;

         __asm{

                   push exitcode

                   push 0

                   push pcode

                   push pExit

                   jmp pFree

         }*/

        return 0;

}

void__stdcall TrulyUnloadDLLAndExitThread(HMODULE hmod,DWORD exitcode)

{

UCHAR shellcode[10]=

"\x48\x83\xEC\x28"//4

"\x52"            //5

"\x41\xFF\xE0";   //8         

        void* p=(BYTE*)GlobalAlloc(GMEM_FIXED,300);

         memset(p,0xcc,300);

         memcpy(p,DoTrulyUnloadDLLAndExitThread,200);

         memcpy((char*)p+200,shellcode,sizeof(shellcode));

         DWORD oldpro;

         VirtualProtect(p,300,PAGE_EXECUTE_READWRITE,&oldpro);   

        typedef long (__stdcall *ptFun)(myEnvir* par,HMODULE hmod,DWORD exitcode,void* pcode);

         ptFun pFun=(ptFun)p;

         myEnvir par={GetProcAddress,FreeLibrary,ExitThread,GlobalFree};

         pFun(&par,hmod,exitcode,p);

}

2014-02-13

相關推薦

DLLShellcode完全解除安裝自身

原創文章,轉載請貼出處 遠端注入時有一個不痛不癢的問題,DLL與shellcode如何解除安裝自身,做到無痕清除? 由於我的DLL自解除安裝用到了Shellcode,所以兩個問題都需要解決。 DLL解除安裝一般使用FreeLibrary,但是如果DLL自己Free自己,會遇到下一條指令(eip/rip)無效

Python學習筆記【Nginx】:Nginx使用完全解除安裝

 安裝與啟動nginx 第一步:通過指令安裝包 sudo apt  install nginx  sudo apt install nginx   第二步:安裝成功後檢視相關配置檔案 ls /etc/nginx/ 在這裡主要是 conf.d

Oracle11g完全解除安裝安裝失敗處理方法

Oracle的解除安裝方法 在我的電腦Oracle安裝目錄下找到deinstall 資料夾(C:\app\youmingke\product\11.2.0\dbhome_1\deinstall ) ,其下面有一個deinstall.bat檔案,點選執行,傻瓜式解除安裝即可。若

Oracle11g完全解除安裝重灌之後Enterprise Manager配置失敗問題的解決

因為第一次安裝選擇了桌面類,然後想重灌成伺服器類。於是經歷了昨天一整天的折磨,終於暫時看不到明顯要解決的問題了。推薦兩篇大神的部落格,主要解決步驟就是參考這兩篇文章,一篇講完全解除安裝的步驟,另一篇是遇到的問題的解決方法。 http://blog.csdn.net/mach

SQL Server 2008 R2 完全解除安裝重新安裝

由於第一次安裝時,SQL Server 服務賬戶和windows使用者登入名設定一致,導致資料庫引擎服務失敗。後轉到管理員賬戶完全解除安裝並重新安裝。 一、解除安裝 1.用administrator賬戶登入 2.控制面板中,解除安裝SQL 2008 R2相關程式 3.刪除安

VS2008完全解除安裝工具

轉載自:http://www.cnblogs.com/yeqw1985/archive/2013/02/21/2921238.html 你是否為解除安裝Visual Studio 2008而煩惱 ?因為Visual Studio 2008太多外掛了,手動解除安裝實在太慢了。。現在有自動解除安裝

完全解除安裝_Office

背景 很多時候,我們都要更新軟體,Office也不例外。我用膩了Office_2007,大爺今天就要換了你,咋地? 操作步驟 下載解除安裝工具 選擇對應版本的解除安裝工具,點選選擇“以相容模式執行這個程式” 雙擊執行,等待結束即可

解決計算機器更換網絡卡後,沒有完全解除安裝裝置管理器中舊網絡卡的問題

計算機器更換網絡卡後,裝置管理器中舊網絡卡的設定並沒有刪除掉。如果這時要給換上的新網絡卡設上舊網絡卡的IP,則系統會提示你,IP已經被分配給舊網絡卡了,不能再給新網絡卡設上相同的地址。我終於找到解決辦法了。 開啟在“裝置管理器→檢視→顯示隱藏的裝置”中,找到了那塊舊的網絡卡。這時想要

ubuntu完全解除安裝mysql

可以先用 dpkg --list|grep mysql 檢視自己的mysql有哪些依賴 一、先解除安裝 mysql-common sudo apt-get remove mysql-common 二、然後再解除安裝 sudo apt-get autoremove --purge mys

oracle 11g客戶端如何完全解除安裝

停用oracle服務:進入計算機管理,在服務中,找到oracle開頭的所有服務,右擊選擇停止 在開始選單中,找到Universal Installer,執行Oracle Universal Installer,單擊解除安裝產品 在產

虛擬機器vmware的完全解除安裝

一、解除安裝vmware的作業系統1在 我的計算機 目錄下找到 要解除安裝的作業系統 右鍵選擇 管理2選擇 從磁碟中刪除(注意不要選擇 移除)二、解除安裝整個vmaware1關閉vmware軟體。2停止vm所有服務:(1)下方工作列右擊選擇 工作管理員 開啟,(2)選擇 服務選擇這5項,全部右鍵 停止 服務(

完全解除安裝刪除oracle9i

Windows 2003+Oracle92 安裝位置:E:\oracle   1、開始->設定->控制面板->管理工具->服務  停止所有Oracle服務。 2、開始->程式->Oracle - OraHome92->Oracle Inst

centos 下完全解除安裝 mysql5.6

檢視已經安裝的服務 rpm –qa|grep -i mysql -i 作用是不區分大小寫 yum remove mysql mysql-server mysql-libs compat-mysql51 rm -rf /var/lib/mysql rm /etc/my.cnf 檢視是否

Linux下的軟體Mysql完全解除安裝(包括其依賴和庫等殘留檔案)

原文:https://blog.csdn.net/zeng308041977/article/details/75245795 使用yum安裝的時候會自動把依賴包安裝上,但是我們一般解除安裝的時候以為只要刪除之前安裝的那個包就可以了,其實不然。因為你使用yum方式安裝,其依賴包也會被自動

手動完全解除安裝Office

1 當然出現安裝錯誤,或是無法安裝先考慮官方解除安裝工具解除安裝,執行後要是解決了問題是最好的。畢竟手動刪除比較麻煩。 開始我們先停止 Office Source Engine 服務。以windows7為例子,在桌面右鍵單擊我的電腦,選擇管理,在開啟的窗口裡

office怎麼解除安裝乾淨,Office for Mac完全解除安裝教程

有小夥伴表示office安裝出錯?那是因為你原先安裝Office沒有解除安裝乾淨,想要完全解除安裝掉Office 2016 for Mac是一件非常複雜的事情,需要刪除安裝的應用程式,支援的檔案和鑰匙串條目等等檔案,今天小編就為大家帶來了非常詳細的Office 2016 for Mac完全解除安裝詳

Oracle資料庫——完全解除安裝步驟

轉載請標明原創地址:https://blog.csdn.net/machinecat0898/article/details/7792471 完全解除安裝oracle11g步驟: 1. 開始-> 設定-> 控制面板-> 管理工具-> 服務 停止所有Oracle服務。 2.

win7 下如何完全解除安裝oracle

Oracle10g刪除,解除安裝步驟如下,只供參考: 1、在系統服務中停止所有oracle的服務。  2、開啟控制面板,程式解除安裝,解除安裝所有有關oracle的程式   3、點選“開始,所有程式”找到oracle主程式下的Oracle Installat

MySQL5.7完全解除安裝步驟詳解

本文主要針對MySQL重裝出現的各種解除安裝不乾淨問題做了詳細整理,希望對各位有所幫助,有疑問可以留言交流 主要介紹完全解除安裝mysql的具體步驟:包括停止服務、解除安裝相關程式、刪除登錄檔等等1、停止MySQL服務2、解除安裝MySQL相關的程式 step1:本次是win10系統環境;左

Mac OS X下完全解除安裝MySQLsudo rm /usr/local/mysql sudo rm -rf /usr/local/mysql* sudo rm -rf /Library/Startu

轉載自:https://blog.csdn.net/u012721519/article/details/55002626 Mac OS X下刪除MySQL是一件非常麻煩的事情,很多時候都不能完全刪除,最終導致MySQL在Mac下的使用非常麻煩。下面我將介紹MySQL如何完全解除安裝的方法。