手工加载API函数

恶意软件为了反调试/反汇编、使用的一种安全技术。

参考链接:

https://kibazen.cn/win32-xia-fs-ji-cun-qi-teb-he-peb-xiang-jie/

实现思路

  1. 利用PEB处获取module base
  2. 根据pe导出表结构获取导出函数GetProcAddr地址
  3. 调用GetProcAddr加载其他api函数
cpp 复制代码
FARPROC sp5Shellcode_NoneThread(void* param)
{
    int ret = 0;
    HMODULE hUser32 = 0;
    HMODULE hModuleBase = 0;
    ptrGetProcAddress lpGetProcAddress;
    ptrLoadLibraryA lpLoadLibraryA = 0;
    ptrCreateThread lpCreateThread = 0;
    ptrCreateFileA lpCreateFileA = 0;
    ptrCloseHandle lpCloseHandle = 0;
    ptrSendMessageA lpSendMessageA = 0;
    ptrSleep lpSleep = 0;
    ptrMessageBoxA lpMessageBoxA = 0;
    ptrVirtualAlloc lpVirtualAlloc = 0;
    ptrEnumWindows lpEnumWindows = 0;

    ptrIsWindowVisible lpIsWindowVisible = 0;
    ptrgetpeername lpgetpeername;
    ptrgetsockopt lpgetsockopt;
    ptrWSAStartup lpWSAStartup;
    ptrsend lpsend;
    ptrntohs lpntohs;
    __asm
    {
        mov eax, fs: [30h]	//PEB
        mov eax, [eax + 0ch]	//_PER_LDR_DATA 
        mov eax, [eax + 14h]//InMemoryOrderModuleList
        mov eax, [eax]
        mov eax, [eax]
        mov eax, [eax + 10h]
        mov hModuleBase, eax
    }

    if (hModuleBase == 0) {
        return 0;
    }

    PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase;
    PIMAGE_NT_HEADERS32 lpNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)hModuleBase + lpDosHeader->e_lfanew);
    if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) {
        return NULL;
    }
    if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {
        return NULL;
    }
    PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hModuleBase +
        (DWORD)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    PDWORD lpdwFunName = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNames);
    PWORD lpword = (PWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNameOrdinals);
    PDWORD lpdwFunAddr = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfFunctions);

    

    for (DWORD dwLoop = 0; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++) {
        char* pFunName = (char*)(lpdwFunName[dwLoop] + (DWORD)hModuleBase);

        if (pFunName[0] == 'G' &&
            pFunName[1] == 'e' &&
            pFunName[2] == 't' &&
            pFunName[3] == 'P' &&
            pFunName[4] == 'r' &&
            pFunName[5] == 'o' &&
            pFunName[6] == 'c' &&
            pFunName[7] == 'A' &&
            pFunName[8] == 'd' &&
            pFunName[9] == 'd' &&
            pFunName[10] == 'r' &&
            pFunName[11] == 'e' &&
            pFunName[12] == 's' &&
            pFunName[13] == 's')
        {
            lpGetProcAddress = (ptrGetProcAddress)(lpdwFunAddr[lpword[dwLoop]] + (DWORD)hModuleBase);
            break;
        }
    }

    char szSleep[] = { 'S','l','e','e','p',0 };

    char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };

    char szCreateThread[] = { 'C','r','e','a','t','e','T','h','r','e','a','d',0 };

    char szCreateFileA[] = { 'C','r','e','a','t','e','F','i','l','e','A',0 };

    char szCloseHandle[]{ 'C','l','o','s','e','H','a','n','d','l','e',0 };

    char szMessageBoxA[]{ 'M','e','s','s','a','g','e','B','o','x','A',0 };

    char szVirtualAlloc[] = { 'V','i','r','t','u','a','l','A','l','l','o','c',0 };

    lpLoadLibraryA = (ptrLoadLibraryA)lpGetProcAddress(hModuleBase, szLoadLibraryA);

    lpCreateThread = (ptrCreateThread)lpGetProcAddress(hModuleBase, szCreateThread);

    lpCloseHandle = (ptrCloseHandle)lpGetProcAddress(hModuleBase, szCloseHandle);

    lpCreateFileA = (ptrCreateFileA)lpGetProcAddress(hModuleBase, szCreateFileA);

    lpSleep = (ptrSleep)lpGetProcAddress(hModuleBase, szSleep);

    lpVirtualAlloc = (ptrVirtualAlloc)lpGetProcAddress(hModuleBase, szVirtualAlloc);

    char szUser32[] = { 'U','s','e','r','3','2','.','d','l','l',0 };
    hUser32 = lpLoadLibraryA(szUser32);

PEB TEB等数据结构

cpp 复制代码
#define PEB_BASE (0x7ffdf000)

typedef struct _NT_TIB
{                                           // Size: 01C
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 000
    PVOID StackBase;                        // 004
    PVOID StackLimit;                       // 008
    PVOID SubSystemTib;                     // 00C
    union                                   // 010
    {
        PVOID FiberData;
        ULONG Version;
    };
    PVOID ArbitraryUserPointer;             // 014
    struct _NT_TIB *Self;                   // 018
} NT_TIB, *PNT_TIB;

typedef struct _TEB
{                                           // Size:  FBC
    NT_TIB Tib;                             // 000
    PVOID EnvironmentPointer;               // 01C
    CLIENT_ID Cid;                          // 020
    PVOID ActiveRpcHandle;                  // 028
    PVOID ThreadLocalStoragePointer;        // 02C
    struct _PEB *ProcessEnvironmentBlock;   // 030
    ULONG LastErrorValue;                   // 034
    ULONG CountOfOwnedCriticalSections;     // 038
    PVOID CsrClientThread;                  // 03C
    struct _W32THREAD* Win32ThreadInfo;     // 040
    ULONG User32Reserved[0x1A];             // 044
    ULONG UserReserved[5];                  // 0AC
    PVOID WOW32Reserved;                    // 0C0
    LCID CurrentLocale;                     // 0C4
    ULONG FpSoftwareStatusRegister;         // 0C8
    PVOID SystemReserved1[0x36];            // 0CC
    LONG ExceptionCode;                     // 1A4
    struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; // 1A8
    UCHAR SpareBytes1[0x28];                // 1AC
    GDI_TEB_BATCH GdiTebBatch;              // 1D4
    CLIENT_ID RealClientId;                 // 6B4
    PVOID GdiCachedProcessHandle;           // 6BC
    ULONG GdiClientPID;                     // 6C0
    ULONG GdiClientTID;                     // 6C4
    PVOID GdiThreadLocalInfo;               // 6C8
    ULONG Win32ClientInfo[62];              // 6CC
    PVOID glDispatchTable[0xE9];            // 7C4
    ULONG glReserved1[0x1D];                // B68
    PVOID glReserved2;                      // BDC
    PVOID glSectionInfo;                    // BE0
    PVOID glSection;                        // BE4
    PVOID glTable;                          // BE8
    PVOID glCurrentRC;                      // BEC
    PVOID glContext;                        // BF0
    NTSTATUS LastStatusValue;               // BF4
    UNICODE_STRING StaticUnicodeString;     // BF8
    WCHAR StaticUnicodeBuffer[0x105];       // C00
    PVOID DeallocationStack;                // E0C
    PVOID TlsSlots[0x40];                   // E10
    LIST_ENTRY TlsLinks;                    // F10
    PVOID Vdm;                              // F18
    PVOID ReservedForNtRpc;                 // F1C
    PVOID DbgSsReserved[0x2];               // F20
    ULONG HardErrorDisabled;                // F28
    PVOID Instrumentation[14];              // F2C
    PVOID SubProcessTag;                    // F64
    PVOID EtwTraceData;                     // F68
    PVOID WinSockData;                      // F6C
    ULONG GdiBatchCount;                    // F70
    BOOLEAN InDbgPrint;                     // F74
    BOOLEAN FreeStackOnTermination;         // F75
    BOOLEAN HasFiberData;                   // F76
    UCHAR IdealProcessor;                   // F77
    ULONG GuaranteedStackBytes;             // F78
    PVOID ReservedForPerf;                  // F7C
    PVOID ReservedForOle;                   // F80
    ULONG WaitingOnLoaderLock;              // F84
    ULONG SparePointer1;                    // F88
    ULONG SoftPatchPtr1;                    // F8C
    ULONG SoftPatchPtr2;                    // F90
    PVOID *TlsExpansionSlots;               // F94
    ULONG ImpersionationLocale;             // F98
    ULONG IsImpersonating;                  // F9C
    PVOID NlsCache;                         // FA0
    PVOID pShimData;                        // FA4
    ULONG HeapVirualAffinity;               // FA8
    PVOID CurrentTransactionHandle;         // FAC
    PTEB_ACTIVE_FRAME ActiveFrame;          // FB0
    PVOID FlsData;                          // FB4
    UCHAR SafeThunkCall;                    // FB8
    UCHAR BooleanSpare[3];                  // FB9
} TEB, *PTEB;

typedef struct _LIST_ENTRY
{                                           // Size: 008
    struct _LIST_ENTRY *Flink;              // 000 从前到后
    struct _LIST_ENTRY *Blink;              // 004 从后到前
} LIST_ENTRY, *PLIST_ENTRY;

typedef struct _PER_LDR_DATA
{                                           // Size: 0024
    ULONG Length;                           // 000
    BOOLEAN Initialize;                     // 004
    PVOID SsHandle;                         // 008
    LIST_ENTRY InLoadOrderModuleList;       // 00C
    LIST_ENTRY InMemoryOrderModuleList;     // 014
    LIST_ENTRY InInitializationOrderModuleList; // 01C
} PER_LDR_DATA, *PPER_LDR_DATA;

typedef struct _UNICODE_STRING
{                                           // Size: 008
  USHORT  Length;                           // 000 占用的内存字节数,个数*2;
  USHORT  MaximumLength;                    // 002
  PWSTR  Buffer;                            // 004
} UNICODE_STRING ,*PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY
{                                           // Size: 050
     LIST_ENTRY InLoadOrderLinks;           // 000 LIST_ENTRY里的Flink和Blink其实是指向LDR_MODULE结构,即LDR_DATA_TABLE_ENTRY
     LIST_ENTRY InMemoryOrderLinks;         // 008 同上
     LIST_ENTRY InInitializationOrderLinks; // 010 同上
     PVOID DllBase;                         // 018
     PVOID EntryPoint;                      // 01C
     ULONG SizeOfImage;                     // 020
     UNICODE_STRING FullDllName;            // 024
     UNICODE_STRING BaseDllName;            // 02C
     ULONG Flags;                           // 034
     WORD LoadCount;                        // 038
     WORD TlsIndex;                         // 03A
     union                                  // 03C
     {
          LIST_ENTRY HashLinks;             // 03C
          struct
          {
               PVOID SectionPointer;        // 03C
               ULONG CheckSum;              // 040
          };
     };
     union
     {
          ULONG TimeDateStamp;              // 044
          PVOID LoadedImports;              // 044
     };
     _ACTIVATION_CONTEXT * EntryPointActivationContext; // 048
     PVOID PatchInformation;                // 04C
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB
{                                           // Size: 1D8
    UCHAR InheritedAddressSpace;            // 000
    UCHAR ReadImageFileExecOptions;         // 001
    UCHAR BeingDebugged;                    // 002
    UCHAR SpareBool;                        // 003 Allocation size
    HANDLE Mutant;                          // 004
    HINSTANCE ImageBaseAddress;             // 008
    struct _PER_LDR_DATA *Ldr;              // 00C
    strcut _RTL_USER_PPROCESS_PARAMETERS *ProcessParameters; // 010
    ULONG SubSystemData;                    // 014
    HANDLE DefaultHeap;                     // 018
    KSPIN_LOCK FastPebLock;                 // 01C
    ULONG FastPebLockRoutine;               // 020
    ULONG FastPebUnlockRoutine;             // 024
    ULONG EnvironmentUpdateCount;           // 028
    ULONG KernelCallbackTable;              // 02C
    LARGE_INTEGER SystemReserved;           // 030
    struct _PER_FREE_BLOCK *FreeList;       // 038
    ULONG TlsExpansionCounter;              // 03C
    ULONG TlsBitmap;                        // 040
    LARGE_INTEGER TlsBitmapBits;            // 044
    ULONG ReadOnlySharedMemoryBase;         // 04C
    ULONG ReadOnlySharedMemoryHeap;         // 050
    ULONG ReadOnlyStaticServerData;         // 054
    ULONG AnsiCodePageData;                 // 058
    ULONG OemCodePageData;                  // 05C
    ULONG UnicodeCaseTableData;             // 060
    ULONG NumberOfProcessors;               // 064
    LARGE_INTEGER NtGlobalFlag;             // 068 Address of a local copy
    LARGE_INTEGER CriticalSectionTimeout;   // 070
    ULONG HeapSegmentReserve;               // 078
    ULONG HeapSegmentCommit;                // 07C
    ULONG HeapDeCommitTotalFreeThreshold;   // 080
    ULONG HeapDeCommitFreeBlockThreshold;   // 084
    ULONG NumberOfHeaps;                    // 088
    ULONG MaximumNumberOfHeaps;             // 08C
    ULONG ProcessHeaps;                     // 090
    ULONG GdiSharedHandleTable;             // 094
    ULONG ProcessStarterHelper;             // 098
    ULONG GdiDCAttributeList;               // 09C
    KSPIN_LOCK LoaderLock;                  // 0A0
    ULONG OSMajorVersion;                   // 0A4
    ULONG OSMinorVersion;                   // 0A8
    USHORT OSBuildNumber;                   // 0AC
    USHORT OSCSDVersion;                    // 0AE
    ULONG OSPlatformId;                     // 0B0
    ULONG ImageSubsystem;                   // 0B4
    ULONG ImageSubsystemMajorVersion;       // 0B8
    ULONG ImageSubsystemMinorVersion;       // 0BC
    ULONG ImageProcessAffinityMask;         // 0C0
    ULONG GdiHandleBuffer[0x22];            // 0C4
    ULONG PostProcessInitRoutine;           // 14C
    ULONG TlsExpansionBitmap;               // 150
    UCHAR TlsExpansionBitmapBits[0x80];     // 154
    ULONG SessionId;                        // 1D4
} PEB, *PPEB;
相关推荐
SLD_Allen1 小时前
Purple Llama:Meta开源的LLM安全“紫队”工具箱
安全·开源·llama
Sirius Wu1 小时前
OpenClaw Cron安全约束完整详解
人工智能·安全·aigc
数据知道2 小时前
网络安全职业规划:从入门到高级安全工程师的路径图
安全·web安全·网络安全·渗透测试·职业规划
Gyr02 小时前
关于证书站捡洞这一档事
安全·web安全
其实防守也摸鱼2 小时前
渗透--损坏的对象级别鉴权漏洞(Broken Object Level Authorization, BOLA)
大数据·网络·数据库·学习·tcp/ip·安全·安全威胁分析
IT小白杨3 小时前
多账号环境稳定性由什么决定:指纹、网络、存储如何共同决定账号安全
网络·安全·开源软件·业界资讯·指纹浏览器
明哥聊AI3 小时前
大模型安全攻防实战:从越狱到Prompt注入的攻防全解析(2026最新)
安全·prompt
网安蟹佬霸3 小时前
我国网络安全人才缺口现状、成因与对策研究
安全·web安全
白帽小阳5 小时前
我的AI辅助开发工具链2026版:从编码到部署的全栈智能实践
网络·人工智能·学习·安全·自动化