1.å±å¹åè¯
2.十种注入技巧 | 通用性进程注入技巧研究
3.干货分享丨表哥带你学习导入表及导入表注入
å±å¹åè¯
âé¼ æ å±å¹åè¯âææ¯æ¯å¨çµååå ¸ä¸å¾å°å¹¿æ³å°åºç¨çï¼å¦åéå©æ¹åéå±±è¯é¸ç软件ï¼è¿ä¸ªææ¯çä¼¼ç®åï¼å ¶å®å¨WINDOWSç³»ç»ä¸å®ç°å´æ¯é常å¤æçï¼æ»çæ¥è¯´æ两ç§å®ç°æ¹å¼ï¼
第ä¸ç§ï¼éç¨æªè·å¯¹é¨åGDIçAPIè°ç¨æ¥å®ç°,入源å¦TextOut,TextOutAçã
第äºç§ï¼å¯¹æ¯ä¸ªè®¾å¤ä¸ä¸æ(DC)åä¸åCopy,并è·è¸ªææä¿®æ¹ä¸ä¸æ(DC)çæä½ã
第äºç§æ¹æ³æ´å¼ºå¤§,ä½å ¼å®¹æ§ä¸å¥½ï¼è第ä¸ç§æ¹æ³ä½¿ç¨çæªè·WindowsAPIçè°ç¨ï¼è¿é¡¹ææ¯ç强大å¯è½è¿è¿è¶ åºäºæ¨çæ³è±¡ï¼æ¯«ä¸å¤¸å¼ ç说ï¼å©ç¨WindowsAPIæ¦æªææ¯ï¼ä½ å¯ä»¥æ¹é æ´ä¸ªæä½ç³»ç»ï¼äºå®ä¸å¾å¤å¤æå¼Windowsä¸æå¹³å°å°±æ¯è¿ä¹å®ç°çï¼èè¿é¡¹ææ¯ä¹æ£æ¯è¿ç¯æç« ç主é¢ã
æªWindowsAPIçè°ç¨ï¼å ·ä½ç说æ¥ä¹å¯ä»¥å为两ç§æ¹æ³ï¼
第ä¸ç§æ¹æ³éè¿ç´æ¥æ¹åWinAPI å¨å åä¸çæ åï¼åµå ¥æ±ç¼ä»£ç ï¼ä½¿ä¹è¢«è°ç¨æ¶è·³è½¬å°æå®çå°åè¿è¡æ¥æªè·ï¼ç¬¬äºç§æ¹æ³åæ¹åIATï¼Import Address Table è¾å ¥å°å表ï¼ï¼éå®åWinAPIå½æ°çè°ç¨æ¥å®ç°å¯¹WinAPIçæªè·ã
第ä¸ç§æ¹æ³çå®ç°è¾ä¸ºç¹çï¼èä¸å¨Winãä¸é¢æ´æé¾åº¦ï¼è¿æ¯å 为è½ç¶å¾®è½¯è¯´WINçAPIåªæ¯ä¸ºäºå ¼å®¹æ§æä¿çä¸æ¥ï¼ç¨åºååºè¯¥å°½å¯è½å°è°ç¨ä½çAPI,å®é ä¸æ ¹æ¬å°±ä¸æ¯è¿æ ·ï¼WIN 9Xå é¨ç大é¨åä½APIç»è¿åæ¢è°ç¨äºååçä½APIï¼ä¹å°±æ¯è¯´æ们éè¦å¨æ¦æªçå½æ°ä¸åµå ¥ä½æ±ç¼ä»£ç ï¼
æ们å°è¦ä»ç»çæ¯ç¬¬äºç§æ¦æªæ¹æ³ï¼è¿ç§æ¹æ³å¨WinãåNTä¸é¢è¿è¡é½æ¯è¾ç¨³å®ï¼å ¼å®¹æ§è¾å¥½ãç±äºéè¦ç¨å°å ³äºWindowsèæå åç管çãæç ´è¿ç¨è¾¹çå¢ãååºç¨ç¨åºçè¿ç¨ç©ºé´ä¸æ³¨å ¥ä»£ç ãPEï¼Portable Executableï¼æä»¶æ ¼å¼åIATï¼è¾å ¥å°å表ï¼çè¾åºå±çç¥è¯ï¼æ以æ们å 对æ¶åå°çè¿äºç¥è¯å¤§æ¦å°åä¸ä¸ªä»ç»ï¼æåä¼ç»åºæ¦æªé¨åçå ³é®ä»£ç ã
å 说Windowsèæå åç管çãWindows9Xç»æ¯ä¸ä¸ªè¿ç¨åé äº4GBçå°å空é´ï¼å¯¹äºNTæ¥è¯´ï¼è¿ä¸ªæ°åæ¯2GBï¼ç³»ç»ä¿çäº2GBå° 4GBä¹é´çå°å空é´ç¦æ¢è¿ç¨è®¿é®ï¼èå¨Win9Xä¸ï¼2GBå°4GBè¿é¨åèæå°å空é´å®é ä¸æ¯ç±ææçWINè¿ç¨æå ±äº«çï¼è¿é¨åå°å空é´å è½½äºå ±äº«Win DLLãå åæ å°æ件åVXDãå å管çå¨åæ件系ç»ç ï¼Win9Xä¸è¿é¨å对äºæ¯ä¸ä¸ªè¿ç¨é½æ¯å¯è§çï¼è¿ä¹æ¯Win9Xæä½ç³»ç»ä¸å¤å¥å£®çåå ã
Win9Xä¸ä¸ºä½æä½ç³»ç»ä¿çäº0å°4MBçå°å空é´ï¼èå¨4MBå°2GBä¹é´ä¹å°±æ¯Winè¿ç¨ç§æçå°å空é´ï¼ç±äº æ¯ä¸ªè¿ç¨çå°å空é´é½æ¯ç¸å¯¹ç¬ç«çï¼ä¹å°±æ¯è¯´ï¼å¦æç¨åºæ³æªè·å ¶å®è¿ç¨ä¸çAPIè°ç¨ï¼å°±å¿ é¡»æç ´è¿ç¨è¾¹çå¢ï¼åå ¶å®çè¿ç¨ä¸æ³¨å ¥æªè·APIè°ç¨ç代ç ï¼è¿é¡¹å·¥ä½æ们交ç»é©åå½æ°ï¼SetWindowsHookExï¼æ¥å®æï¼å ³äºå¦ä½å建ä¸ä¸ªå å«ç³»ç»é©åçå¨æé¾æ¥åºï¼ãçµèé«ææå¿ãå·²ç»æè¿ä¸é¢ä»ç»äºï¼è¿éå°±ä¸èµè¿°äºã
ææç³»ç»é©åçå½æ°å¿ é¡»è¦å¨å¨æåºéï¼è¿æ ·çè¯ï¼å½è¿ç¨éå¼ææ¾å¼è°ç¨ä¸ä¸ªå¨æåºéçå½æ°æ¶ï¼ç³»ç»ä¼æè¿ä¸ªå¨æåºæ å°å°è¿ä¸ªè¿ç¨çèæå°å空é´éï¼è¿ä½¿å¾DLLæ为è¿ç¨çä¸é¨åï¼ä»¥è¿ä¸ªè¿ç¨ç身份æ§è¡ï¼ä½¿ç¨è¿ä¸ªè¿ç¨çå æ ï¼ä¹å°±æ¯è¯´å¨æé¾æ¥åºä¸ç代ç 被é©åå½æ°æ³¨å ¥äºå ¶å®GUIè¿ç¨çå°å空é´ï¼éGUIè¿ç¨ï¼é©åå½æ°å°±æ è½ä¸ºåäºï¼ï¼å½å å«é©åçDLLæ³¨å ¥å ¶å®è¿ç¨åï¼å°±å¯ä»¥åå¾æ å°å°è¿ä¸ªè¿ç¨èæå åéçå个模åï¼EXEåDLLï¼çåºå°åï¼å¦ï¼
HMODULE hmodule=GetModuleHandle(âMypro.exeâ);
å¨MFCç¨åºä¸,æ们å¯ä»¥ç¨AfxGetInstanceHandle()å½æ°æ¥å¾å°æ¨¡åçåºå°åãEXEåDLL被æ å°å°èæå å空é´çä»ä¹å°æ¹æ¯ç±å®ä»¬çåºå°åå³å®çãå®ä»¬çåºå°åæ¯å¨é¾æ¥æ¶ç±é¾æ¥å¨å³å®çãå½ä½ æ°å»ºä¸ä¸ªWinå·¥ç¨æ¶ï¼VCï¼ï¼é¾æ¥å¨ä½¿ç¨ç¼ºççåºå°å0xãå¯ä»¥éè¿é¾æ¥å¨çBASEé项æ¹å模åçåºå°åãEXEé常被æ å°å°èæå åç0xå¤ï¼DLLä¹éä¹æä¸åçåºå°åï¼é常被æ å°å°ä¸åè¿ç¨çç¸åçèæå°å空é´å¤ã
ç³»ç»å°EXEåDLLåå°ä¸å¨æ å°å°èæå å空é´ä¸ï¼å®ä»¬å¨å åä¸çç»æä¸ç£çä¸çéææ件ç»ææ¯ä¸æ ·çãå³PE (Portable Executable) æä»¶æ ¼å¼ãæ们å¾å°äºè¿ç¨æ¨¡åçåºå°å以åï¼å°±å¯ä»¥æ ¹æ®PEæ件çæ ¼å¼ç©·ä¸¾è¿ä¸ªæ¨¡åçIMAGE_IMPORT_DESCRIPTORæ°ç»ï¼ççè¿ç¨ç©ºé´ä¸æ¯å¦å¼å ¥äºæ们éè¦æªè·çå½æ°æå¨çå¨æé¾æ¥åºï¼æ¯å¦éè¦æªè·âTextOutAâï¼å°±å¿ é¡»æ£æ¥âGdi.dllâæ¯å¦è¢«å¼å ¥äºã
说å°è¿éï¼æ们æå¿ è¦ä»ç»ä¸ä¸PEæ件çæ ¼å¼ï¼å¦å³å¾ï¼è¿æ¯PEæä»¶æ ¼å¼ç大è´æ¡å¾ï¼æåé¢æ¯æ件头ï¼æ们ä¸å¿ çä¼ï¼ä»PE File Optional Headeråé¢å¼å§ï¼å°±æ¯æ件ä¸å个段ç说æï¼è¯´æåé¢ææ¯çæ£ç段æ°æ®ï¼èå®é ä¸æä»¬å ³å¿çåªæä¸ä¸ªæ®µï¼é£å°±æ¯â.idataâ段ï¼è¿ä¸ªæ®µä¸å å«äºææçå¼å ¥å½æ°ä¿¡æ¯ï¼è¿æIATï¼Import Address Tableï¼çRVAï¼Relative Virtual Addressï¼å°åã
说å°è¿éï¼æªè·WindowsAPIçæ´ä¸ªåçå°±è¦çç¸å¤§ç½äºãå®é ä¸ææè¿ç¨å¯¹ç»å®çAPIå½æ°çè°ç¨æ»æ¯éè¿PEæ件çä¸ä¸ªå°æ¹æ¥è½¬ç§»çï¼è¿å°±æ¯ä¸ä¸ªè¯¥æ¨¡å(å¯ä»¥æ¯EXEæDLL)çâ.idataâ段ä¸çIATè¾å ¥å°å表ï¼Import Address Tableï¼ãå¨é£éææææ¬æ¨¡åè°ç¨çå ¶å®DLLçå½æ°ååå°åãå¯¹å ¶å®DLLçå½æ°è°ç¨å®é ä¸åªæ¯è·³è½¬å°è¾å ¥å°å表ï¼ç±è¾å ¥å°å表å跳转å°DLLçæ£çå½æ°å ¥å£ã
å ·ä½æ¥è¯´ï¼æ们å°éè¿IMAGE_IMPORT_DESCRIPTORæ°ç»æ¥è®¿é®â.idataâ段ä¸å¼å ¥çDLLçä¿¡æ¯ï¼ç¶åéè¿IMAGE_THUNK_DATAæ°ç»æ¥é对ä¸ä¸ªè¢«å¼å ¥çDLL访é®è¯¥DLLä¸è¢«å¼å ¥çæ¯ä¸ªå½æ°çä¿¡æ¯ï¼æ¾å°æ们éè¦æªè·çå½æ°ç跳转å°åï¼ç¶åæ¹ææ们èªå·±çå½æ°çå°åâ¦â¦å ·ä½çåæ³å¨åé¢çå ³é®ä»£ç ä¸ä¼æ详ç»ç讲解ã
讲äºè¿ä¹å¤åçï¼ç°å¨è®©æ们åå°âé¼ æ å±å¹åè¯âçä¸é¢ä¸æ¥ãé¤äºAPIå½æ°çæªè·ï¼è¦å®ç°âé¼ æ å±å¹åè¯âï¼è¿éè¦åä¸äºå ¶å®çå·¥ä½ï¼ç®åç说æ¥ï¼å¯ä»¥æä¸ä¸ªå®æ´çåè¯è¿ç¨å½çº³æ以ä¸å 个æ¥éª¤ï¼
1ï¼ å®è£ é¼ æ é©åï¼éè¿é©åå½æ°è·å¾é¼ æ æ¶æ¯ã
使ç¨å°çAPIå½æ°ï¼SetWindowsHookEx
2ï¼ å¾å°é¼ æ çå½åä½ç½®ï¼åé¼ æ ä¸ççªå£åéç»æ¶æ¯ï¼è®©å®è°ç¨ç³»ç»å½æ°éç»çªå£ã
使ç¨å°çAPIå½æ°ï¼WindowFromPointï¼ScreenToClientï¼InvalidateRect
3ï¼ æªè·å¯¹ç³»ç»å½æ°çè°ç¨ï¼åå¾åæ°ï¼ä¹å°±æ¯æ们è¦åçè¯ã
对äºå¤§å¤æ°çWindowsåºç¨ç¨åºæ¥è¯´ï¼å¦æè¦åè¯ï¼æ们éè¦æªè·çæ¯âGdi.dllâä¸çâTextOutAâå½æ°ã
æ们å ä»¿ç §TextOutAå½æ°åä¸ä¸ªèªå·±çMyTextOutAå½æ°ï¼å¦ï¼
BOOL WINAPI MyTextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpszString,int cbString)
{
// è¿éè¿è¡è¾åºlpszStringçå¤ç
// ç¶åè°ç¨æ£ççTextOutAå½æ°
}
æè¿ä¸ªå½æ°æ¾å¨å®è£ äºé©åçå¨æè¿æ¥åºä¸ï¼ç¶åè°ç¨æ们æåç»åºçHookImportFunctionå½æ°æ¥æªè·è¿ç¨å¯¹TextOutAå½æ°çè°ç¨ï¼è·³è½¬å°æ们çMyTextOutAå½æ°ï¼å®æ对è¾åºå符串çææã
HookImportFunctionçç¨æ³ï¼
HOOKFUNCDESC hd;
PROC pOrigFuns;
hd.szFunc="TextOutA";
hd.pProc=(PROC)MyTextOutA;
HookImportFunction (AfxGetInstanceHandle(),"gdi.dll",&hd,pOrigFuns);
ä¸é¢ç»åºäºHookImportFunctionçæºä»£ç ï¼ç¸ä¿¡è¯¦å°½ç注éä¸å®ä¸ä¼è®©æ¨è§å¾ç解æªè·å°åºæ¯æä¹å®ç°çå¾é¾ï¼Ok,Letâs Goï¼
///////////////////////////////////////////// Begin ///////////////////////////////////////////////////////////////
#include <crtdbg.h>
// è¿éå®ä¹äºä¸ä¸ªäº§çæéçå®
#define MakePtr(cast, ptr, AddValue) (cast)((DWORD)(ptr)+(DWORD)(AddValue))
// å®ä¹äºHOOKFUNCDESCç»æ,æ们ç¨è¿ä¸ªç»æä½ä¸ºåæ°ä¼ ç»HookImportFunctionå½æ°
typedef struct tag_HOOKFUNCDESC
{
LPCSTR szFunc; // The name of the function to hook.
PROC pProc; // The procedure to blast in.
} HOOKFUNCDESC , * LPHOOKFUNCDESC;
// è¿ä¸ªå½æ°çæµå½åç³»ç»æ¯å¦æ¯WindowNT
BOOL IsNT();
// è¿ä¸ªå½æ°å¾å°hModule -- å³æ们éè¦æªè·çå½æ°æå¨çDLL模åçå¼å ¥æ述符(import descriptor)
PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule);
// æ们ç主å½æ°
BOOL HookImportFunction(HMODULE hModule, LPCSTR szImportModule,
LPHOOKFUNCDESC paHookFunc, PROC* paOrigFuncs)
{
/////////////////////// ä¸é¢ç代ç æ£æµåæ°çæææ§ ////////////////////////////
_ASSERT(szImportModule);
_ASSERT(!IsBadReadPtr(paHookFunc, sizeof(HOOKFUNCDESC)));
#ifdef _DEBUG
if (paOrigFuncs) _ASSERT(!IsBadWritePtr(paOrigFuncs, sizeof(PROC)));
_ASSERT(paHookFunc.szFunc);
_ASSERT(*paHookFunc.szFunc != '\0');
_ASSERT(!IsBadCodePtr(paHookFunc.pProc));
#endif
if ((szImportModule == NULL) || (IsBadReadPtr(paHookFunc, sizeof(HOOKFUNCDESC))))
{
_ASSERT(FALSE);
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////
// çæµå½å模åæ¯å¦æ¯å¨2GBèæå å空é´ä¹ä¸
// è¿é¨åçå°åå åæ¯å±äºWinè¿ç¨å ±äº«ç
if (!IsNT() && ((DWORD)hModule >= 0x))
{
_ASSERT(FALSE);
SetLastErrorEx(ERROR_INVALID_HANDLE, SLE_ERROR);
return FALSE;
}
// æ¸ é¶
if (paOrigFuncs) memset(paOrigFuncs, NULL, sizeof(PROC));
// è°ç¨GetNamedImportDescriptor()å½æ°,æ¥å¾å°hModule -- å³æ们éè¦
// æªè·çå½æ°æå¨çDLL模åçå¼å ¥æ述符(import descriptor)
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetNamedImportDescriptor(hModule, szImportModule);
if (pImportDesc == NULL)
return FALSE; // è¥ä¸ºç©º,å模åæªè¢«å½åè¿ç¨æå¼å ¥
// ä»DLL模åä¸å¾å°åå§çTHUNKä¿¡æ¯,å 为pImportDesc->FirstThunkæ°ç»ä¸çåå§ä¿¡æ¯å·²ç»
// å¨åºç¨ç¨åºå¼å ¥è¯¥DLLæ¶è¦çä¸äºææçå¼å ¥ä¿¡æ¯,æ以æ们éè¦éè¿åå¾pImportDesc->OriginalFirstThunk
// æéæ¥è®¿é®å¼å ¥å½æ°åçä¿¡æ¯
PIMAGE_THUNK_DATA pOrigThunk = MakePtr(PIMAGE_THUNK_DATA, hModule,
pImportDesc->OriginalFirstThunk);
// ä»pImportDesc->FirstThunkå¾å°IMAGE_THUNK_DATAæ°ç»çæé,ç±äºè¿éå¨DLL被å¼å ¥æ¶å·²ç»å¡«å äº
// ææçå¼å ¥ä¿¡æ¯,æ以çæ£çæªè·å®é ä¸æ£æ¯å¨è¿éè¿è¡ç
PIMAGE_THUNK_DATA pRealThunk = MakePtr(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);
// 穷举IMAGE_THUNK_DATAæ°ç»,寻æ¾æ们éè¦æªè·çå½æ°,è¿æ¯æå ³é®çé¨å!
while (pOrigThunk->u1.Function)
{
// åªå¯»æ¾é£äºæå½æ°åèä¸æ¯åºå·å¼å ¥çå½æ°
if (IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG))
{
// å¾å°å¼å ¥å½æ°çå½æ°å
PIMAGE_IMPORT_BY_NAME pByName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule,
pOrigThunk->u1.AddressOfData);
// å¦æå½æ°å以NULLå¼å§,è·³è¿,继ç»ä¸ä¸ä¸ªå½æ°
if ('\0' == pByName->Name[0])
continue;
// bDoHookç¨æ¥æ£æ¥æ¯å¦æªè·æå
BOOL bDoHook = FALSE;
// æ£æ¥æ¯å¦å½åå½æ°æ¯æ们éè¦æªè·çå½æ°
if ((paHookFunc.szFunc[0] == pByName->Name[0]) &&
(strcmpi(paHookFunc.szFunc, (char*)pByName->Name) == 0))
{
// æ¾å°äº!
if (paHookFunc.pProc)
bDoHook = TRUE;
}
if (bDoHook)
{
// æ们已ç»æ¾å°äºæè¦æªè·çå½æ°,é£ä¹å°±å¼å§å¨æå§
// é¦å è¦åçæ¯æ¹åè¿ä¸åèæå åçå åä¿æ¤ç¶æ,让æ们å¯ä»¥èªç±åå
MEMORY_BASIC_INFORMATION mbi_thunk;
VirtualQuery(pRealThunk, &mbi_thunk, sizeof(MEMORY_BASIC_INFORMATION));
_ASSERT(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
PAGE_READWRITE, &mbi_thunk.Protect));
// ä¿åæ们æè¦æªè·çå½æ°çæ£ç¡®è·³è½¬å°å
if (paOrigFuncs)
paOrigFuncs = (PROC)pRealThunk->u1.Function;
// å°IMAGE_THUNK_DATAæ°ç»ä¸çå½æ°è·³è½¬å°åæ¹å为æ们èªå·±çå½æ°å°å!
// 以åææè¿ç¨å¯¹è¿ä¸ªç³»ç»å½æ°çææè°ç¨é½å°æ为对æ们èªå·±ç¼åçå½æ°çè°ç¨
pRealThunk->u1.Function = (PDWORD)paHookFunc.pProc;
// æä½å®æ¯!å°è¿ä¸åèæå åæ¹ååæ¥çä¿æ¤ç¶æ
DWORD dwOldProtect;
_ASSERT(VirtualProtect(mbi_thunk.BaseAddress, mbi_thunk.RegionSize,
mbi_thunk.Protect, &dwOldProtect));
SetLastError(ERROR_SUCCESS);
return TRUE;
}
}
// 访é®IMAGE_THUNK_DATAæ°ç»ä¸çä¸ä¸ä¸ªå ç´
pOrigThunk++;
pRealThunk++;
}
return TRUE;
}
// GetNamedImportDescriptorå½æ°çå®ç°
PIMAGE_IMPORT_DESCRIPTOR GetNamedImportDescriptor(HMODULE hModule, LPCSTR szImportModule)
{
// æ£æµåæ°
_ASSERT(szImportModule);
_ASSERT(hModule);
if ((szImportModule == NULL) || (hModule == NULL))
{
_ASSERT(FALSE);
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
return NULL;
}
// å¾å°Dosæ件头
PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER) hModule;
// æ£æµæ¯å¦MZæ件头
if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) ||
(pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE))
{
_ASSERT(FALSE);
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
return NULL;
}
// åå¾PEæ件头
PIMAGE_NT_HEADERS pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
// æ£æµæ¯å¦PEæ åæ件
if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
(pNTHeader->Signature != IMAGE_NT_SIGNATURE))
{
_ASSERT(FALSE);
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
return NULL;
}
// æ£æ¥PEæ件çå¼å ¥æ®µ(å³ .idata section)
if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0)
return NULL;
// å¾å°å¼å ¥æ®µ(å³ .idata section)çæé
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader,
pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
// 穷举PIMAGE_IMPORT_DESCRIPTORæ°ç»å¯»æ¾æ们éè¦æªè·çå½æ°æå¨ç模å
while (pImportDesc->Name)
{
PSTR szCurrMod = MakePtr(PSTR, pDOSHeader, pImportDesc->Name);
if (stricmp(szCurrMod, szImportModule) == 0)
break; // æ¾å°!ä¸æ循ç¯
// ä¸ä¸ä¸ªå ç´
pImportDesc++;
}
// å¦æ没ææ¾å°,说ææ们寻æ¾ç模å没æ被å½åçè¿ç¨æå¼å ¥!
if (pImportDesc->Name == NULL)
return NULL;
// è¿åå½æ°ææ¾å°ç模åæ述符(import descriptor)
return pImportDesc;
}
// IsNT()å½æ°çå®ç°
BOOL IsNT()
{
OSVERSIONINFO stOSVI;
memset(&stOSVI, NULL, sizeof(OSVERSIONINFO));
stOSVI.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
BOOL bRet = GetVersionEx(&stOSVI);
_ASSERT(TRUE == bRet);
if (FALSE == bRet) return FALSE;
return (VER_PLATFORM_WIN_NT == stOSVI.dwPlatformId);
}
/////////////////////////////////////////////// End //////////////////////////////////////////////////////////////////////
ä¸ç¥éå¨ä¹åï¼æå¤å°æåå°è¯è¿å»å®ç°âé¼ æ å±å¹åè¯âè¿é¡¹å 满äºææçææ¯ï¼ä¹åªæå°è¯è¿çæåæè½ä½ä¼å°å ¶é´çä¸æï¼å°¤å ¶å¨æ¢ç´¢APIå½æ°çæªè·æ¶ï¼æ头çå ç¯èµæ没æä¸ç¯æ¯æ¶åå°å ³é®ä»£ç çï¼éè¦çå°æ¹é½æ¯ä¸ç¬ä»£è¿ï¼MSDNæ´æ¯æ¾å¾èç½èæ åï¼ä¹ä¸ç¥éé¤äºIMAGE_IMPORT_DESCRIPTORåIMAGE_THUNK_DATAï¼å¾®è½¯è¿éèäºå¤å°ç§å¯ï¼å¥½å¨ç¡¬ç头ç®è¿æ¯æå®ç»æ»å äºï¼å¸æè¿ç¯æç« å¯¹å¤§å®¶è½ææ帮å©ã
十种注入技巧 | 通用性进程注入技巧研究
进程注入是恶意软件和无文件攻击中的一种逃避技术,允许在另一个进程的入源地址空间内运行自定义代码。这种隐蔽性提高了攻击的入源效率。本文将介绍十种常见的入源进程注入技术,以及如何通过这些技术在现实场景中注入恶意代码。入源
1. **DLL注入方式**:利用`CREATEREMOTETHREAD`和`LOADLIBRARY`进行注入是入源自解析源码常用方法。恶意软件将恶意动态链接库(DLL)路径写入目标进程的入源虚拟地址空间,并通过创建远程线程确保其加载。入源图1显示了此过程的入源屏幕截图。
2. **PE文件注入**:此技术允许恶意软件直接在其代码中注入PE文件,入源而无需在磁盘上创建额外的入源DLL。内存中执行的入源繁星刷源码优势在于无需额外文件,但缺点是入源PE文件的新基址可能不可预测,需要动态计算其绝对地址。入源图3展示了这一技术的入源结构。
3. **进程HOLLOWING**:恶意软件可以直接替换宿主进程的内存空间,用恶意可执行文件覆盖合法代码,从而实现隐蔽的注入。图5演示了Ransom.Cryak如何实现进程hollowing。
4. **线程执行劫持**:通过劫持现有线程避免进程或线程创建操作的噪声,提高隐蔽性。图7给出了通用木马程序利用此技术的实例。
5. **SETWINDOWSHOOKEX注入**:利用挂钩技术拦截特定线程事件,svn命令源码加载恶意DLL。Locky Ransomware是使用此技术的一个例子。图9展示了其注入过程。
6. **注册表注入**:通过修改`AppInit_DLLs`、`AppCertDlls`和`IFEO`注册表项实现注入和维持注入。图和分别展示了木乃伊和Diztakun木马如何利用这些技术。
7. **APC注入与AtomBombing**:通过异步过程调用控制线程执行,注入自定义代码。图展示了Amanahe恶意软件使用APC注入的实例。
8. **窗口内存注入 (EWMI)**:PowerLoader等恶意软件利用资源管理器托盘窗口的额外窗口内存注入代码。图显示了注入过程。小说后端源码
9. **SHIMS注入**:恶意软件利用Shims技术实现注入,通过修改API调用路径实现隐蔽。图展示了广告软件“Search Protect by Conduit”使用Shims进行注入和维持的例子。
. **IAT和INLINE HOOKING**:通过修改导入地址表或直接修改API函数本身,实现隐蔽的注入。图演示了FinFisher通过IAT HOOKING技术注入恶意代码。
总结,本文详细介绍了十种不同的进程注入技术,涵盖了直接代码注入、DLL加载、内存注入、电子家谱源码注册表修改、API钩子和隐藏执行等多种方法。这些技术在恶意软件中广泛使用,以提高其隐蔽性和持久性。通过理解这些技术,研究人员和安全专家可以更有效地检测和防御针对这些技术的攻击。
干货分享丨表哥带你学习导入表及导入表注入
导入表概述
导入表在逆向和病毒分析中扮演重要角色,尤其在病毒分析初期,快速查看导入表内容能帮助判断程序使用了哪些功能。导入表位于数据目录项第二位置,程序每次调用DLL都会生成一张表,记录调用的DLL中函数地址。
导入表结构体 IMAGE_IMPORT_DESCRIPTOR
导入表结构包括了调用的DLL信息。
导入绑定技术
程序加载前,IAT表与INT表内容相同,都是DLL中函数名或序号。加载后,IAT表更新为函数真实地址。若在DLL重定位时地址未占据ImageBase,需修复绝对地址。dll修改后,IAT表中函数地址可能变化,需再次修复。
绑定导入技术在Windows记事本中应用。
IMAGE_THUNK_DATA
标识函数以序号或字符串导入,序号表示函数名,字符串指向IMAGE_IMPORT_BY_NAME结构。
IMAGE_IMPORT_BY_NAME
存储输入函数信息。
导入地址表IAT
PE装载器重写IAT表,搜索INT表找到输入函数地址,替换IAT表元素。
非导入绑定情况下,INT与IAT表内容一致。
PE文件加载后,IAT表更新为函数入口地址。
定位导入表
通过数据目录项第二项的VirtualAddress转为FOA,定位导入表结构,打印名称,获取DLL名。
遍历INT表
从导入表定义到INT表,判断是否序号导入,定位并输出函数名称。
遍历IAT表
定义到IAT表,遍历输出函数名称。
实现代码
导入表注入
通过修改exe导入表,将自定义DLL添加,实现加载。
实现步骤
1. 新增节表存储移动后的导入表;
2. 根据目录项获取导入表信息;
3. 将VirtualAddress转为FOA定位导入表;
4. 复制原导入表到空白区;
5. 追加新导入表;
6. 追加INT表、IAT表及IMAGE_IMPORT_BY_NAME结构;
7. 填充结构RVA与DLL名称;
8. 修正IMAGE_DATA_DIRECTORY结构。
手动实现
根据目录项定位导入表,寻找空白区复制原表,追加新表和结构,填充信息,修正表元素。
代码实现
通过以上步骤实现导入表注入,放置DLL并运行程序,成功弹出窗口。
2024-11-25 10:56
2024-11-25 09:33
2024-11-25 09:10
2024-11-25 09:09
2024-11-25 09:00
2024-11-25 08:22