首页
社区
课程
招聘
[未解决,已结帖] [求助][求助][求助]内存加载 疑似TLS问题 100.00雪花
发表于: 2022-5-31 03:01 3966

[未解决,已结帖] [求助][求助][求助]内存加载 疑似TLS问题 100.00雪花

2022-5-31 03:01
3966


内存加载DLL出现Runtime Error,调试发现错误在下面的:

 

79301E1C | A1 04A63379 | mov eax,dword ptr ds:[<brock>] | bedrock_windows.cpp:772
79301E21 | 56 | push esi | bedrock_windows.cpp:773
79301E22 | 8B00 | mov eax,dword ptr ds:[eax] | bedrock_windows.cpp:772 此处eax=0,导致的内存访问异常

 

怀疑是TLS问题,百度找到了上面的tls回调的修复,但实际运行while (*callback) 判断没通过,因为是没有回调函数,可能是TLS变量没修复,但网上找半天没找到相关的资料,请求大佬解惑

 

因为DLL使用了nana gui库出现的问题,内存加载的shellcode经过测试可正常加载C++一般DLL和MFC DLL。

 

ShellCode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#pragma once
 
typedef HMODULE(WINAPI* _LoadLibraryA)(
    IN const char* lpModulName
    );
 
typedef LONG(WINAPI* _GetProcAddress)(
    IN HMODULE       dwModul,
    IN const char* lpProcName
    );
 
typedef LONG(NTAPI* _ZwAllocateVirtualMemory)(
    _In_    HANDLE      ProcessHandle,
    _Inout_ PVOID      BaseAddress,
    _In_    ULONG_PTR   ZeroBits,
    _Inout_ PSIZE_T     RegionSize,
    _In_    ULONG       AllocationType,
    _In_    ULONG       Protect
    );
 
typedef LONG(WINAPI* _DllMain)(
    HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    );
 
typedef LONG(WINAPI* _GetModuleFileName)(
    HMODULE hModule,
    void*   lpFileName,
    size_t  nSize
    );
 
typedef LONG(WINAPI* _MessageBoxA)(
    _In_opt_ HWND hWnd,
    _In_opt_ char* lpText,
    _In_opt_ char* lpCaption,
    _In_ UINT uType);
 
typedef struct _MemLoadInfo
{
    DWORD       LoadBase;                 //  DLL基址
 
    _LoadLibraryA               api_LoadLibraryA;                       //  必须项
    _GetProcAddress             api_GetProcAddress;                     //  必须项
    _ZwAllocateVirtualMemory    api_ZwAllocateVirtualMemory;            //  必须项
    _GetModuleFileName          api_GetModuleFileNameA;                 //  可选项
    _GetModuleFileName          api_GetModuleFileNameW;                 //  可选项
    _MessageBoxA                api_MessageBoxA;                        //  可选项
}MemLoadInfo;
 
__declspec(safebuffers) int WINAPI MemLoad(MemLoadInfo* pMemLoad)
{
    if (pMemLoad == 0)
        return 1;
 
    if (pMemLoad->LoadBase == 0 || pMemLoad->api_LoadLibraryA == 0 || pMemLoad->api_GetProcAddress == 0 || pMemLoad->api_ZwAllocateVirtualMemory == 0)
        return 2;
 
    IMAGE_DOS_HEADER*       pDosHeader;
    IMAGE_NT_HEADERS*       pNtHeader;
    IMAGE_SECTION_HEADER*   pSectionHeader;
 
    pDosHeader = (IMAGE_DOS_HEADER*)pMemLoad->LoadBase;
 
    if (pDosHeader == 0)
        return 3;
    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
        return 4;
 
    pNtHeader = (IMAGE_NT_HEADERS*)(pMemLoad->LoadBase + pDosHeader->e_lfanew);
    if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
        return 5;
 
    if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0 || pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0)
        return 6;
 
    DWORD InitBase = 0;
    DWORD* Proc_GetModulFileNameA = 0;
    DWORD* Proc_GetModulFileNameW = 0;
 
    DWORD Size_GetModulFileNameA = 0x100;
    DWORD Size_GetModulFileNameW = 0x100;
    pMemLoad->api_ZwAllocateVirtualMemory((HANDLE)-1, &InitBase, NULL, &pNtHeader->OptionalHeader.SizeOfImage, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 
    //  分配一段 GetModulFileName的回调代码
    if (pMemLoad->api_GetModuleFileNameA) {
        pMemLoad->api_ZwAllocateVirtualMemory((HANDLE)-1, &Proc_GetModulFileNameA, NULL, &Size_GetModulFileNameA, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (Proc_GetModulFileNameA == 0)
            return 7;
        Proc_GetModulFileNameA[0] = 0x8BEC8B55; Proc_GetModulFileNameA[1] = 0x003D0845; Proc_GetModulFileNameA[2] = 0x75004010;
        Proc_GetModulFileNameA[3] = 0x0C458B1D; Proc_GetModulFileNameA[4] = 0x3A4300C7; Proc_GetModulFileNameA[5] = 0x40C7315C;
        Proc_GetModulFileNameA[6] = 0x6C642E04; Proc_GetModulFileNameA[7] = 0x0840C66C; Proc_GetModulFileNameA[8] = 0x0008B800;
        Proc_GetModulFileNameA[9] = 0xC25D0000; Proc_GetModulFileNameA[10] = 0x4589000C; Proc_GetModulFileNameA[11] = 0x1000B808;
        Proc_GetModulFileNameA[12] = 0xFF5D0040; Proc_GetModulFileNameA[13] = 0xCCCCCCE0;
        *(DWORD*)((DWORD)Proc_GetModulFileNameA + 7) = InitBase;
        *(DWORD*)((DWORD)Proc_GetModulFileNameA + 46) = (DWORD)pMemLoad->api_GetModuleFileNameA;
    }
    if (pMemLoad->api_GetModuleFileNameW) {
        pMemLoad->api_ZwAllocateVirtualMemory((HANDLE)-1, &Proc_GetModulFileNameW, NULL, &Size_GetModulFileNameW, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (Proc_GetModulFileNameW == 0)
            return 7;
        Proc_GetModulFileNameW[0] = 0x8BEC8B55; Proc_GetModulFileNameW[1] = 0x003D0845; Proc_GetModulFileNameW[2] = 0x75004010;
        Proc_GetModulFileNameW[3] = 0x0C458B2D; Proc_GetModulFileNameW[4] = 0x00C7C933; Proc_GetModulFileNameW[5] = 0x003A0043;
        Proc_GetModulFileNameW[6] = 0x5C0440C7; Proc_GetModulFileNameW[7] = 0xC7003100; Proc_GetModulFileNameW[8] = 0x002E0840;
        Proc_GetModulFileNameW[9] = 0x40C70064; Proc_GetModulFileNameW[10] = 0x6C006C0C; Proc_GetModulFileNameW[11] = 0x48896600;
        Proc_GetModulFileNameW[12] = 0x0008B810; Proc_GetModulFileNameW[13] = 0xC25D0000; Proc_GetModulFileNameW[14] = 0x4589000C;
        Proc_GetModulFileNameW[15] = 0x1000B808; Proc_GetModulFileNameW[16] = 0xFF5D0040; Proc_GetModulFileNameW[17] = 0xCCCCCCE0;
        *(DWORD*)((DWORD)Proc_GetModulFileNameW + 7) = InitBase;
        *(DWORD*)((DWORD)Proc_GetModulFileNameW + 62) = (DWORD)pMemLoad->api_GetModuleFileNameW;
    }
 
    if (InitBase == 0)
        return 7;
 
    //  复制头和节表
    for (size_t i = 0; i < pNtHeader->OptionalHeader.SizeOfHeaders; i++)
        *(byte*)(InitBase + i) = *(byte*)(pMemLoad->LoadBase + i);
 
    pSectionHeader = (IMAGE_SECTION_HEADER*)(pMemLoad->LoadBase + pDosHeader->e_lfanew + 248);
 
    //  复制区段
    for (size_t i = 0; i < pNtHeader->FileHeader.NumberOfSections; i++)
    {
        for (size_t x = 0; x < pSectionHeader[i].SizeOfRawData; x++)
            *(byte*)(InitBase + pSectionHeader[i].VirtualAddress + x) = *(byte*)(pMemLoad->LoadBase + pSectionHeader[i].PointerToRawData + x);
    }
 
    //  修复IAT
    PIMAGE_DATA_DIRECTORY pDataDirectory;
 
    pDataDirectory = pNtHeader->OptionalHeader.DataDirectory;
 
    if (pDataDirectory[1].Size > 0)
    {
        //获取导入表地址
        PIMAGE_IMPORT_DESCRIPTOR ImportAddr = PIMAGE_IMPORT_DESCRIPTOR(pDataDirectory[1].VirtualAddress + InitBase);
 
        for (; ImportAddr->Name; ++ImportAddr)
        {
            DWORD* thunkRef;
            FARPROC* funcRef;
 
            HMODULE hModule = pMemLoad->api_LoadLibraryA((char*)(InitBase + ImportAddr->Name));
 
            if (ImportAddr->OriginalFirstThunk)
            {
                thunkRef = (DWORD*)(InitBase + ImportAddr->OriginalFirstThunk);
                funcRef = (FARPROC*)(InitBase + ImportAddr->FirstThunk);
            }
            else
            {
                //no hint table
                thunkRef = (DWORD*)(InitBase + ImportAddr->FirstThunk);
                funcRef = (FARPROC*)(InitBase + ImportAddr->FirstThunk);
            }
 
            for (; *thunkRef; ++thunkRef, ++funcRef)
            {
                if (IMAGE_SNAP_BY_ORDINAL(*thunkRef))
                {
                    *funcRef = (FARPROC)pMemLoad->api_GetProcAddress(hModule, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
                }
                else
                {
                    PIMAGE_IMPORT_BY_NAME pFuncName = (PIMAGE_IMPORT_BY_NAME)(*thunkRef + InitBase);
                    *funcRef = (FARPROC)pMemLoad->api_GetProcAddress(hModule, (LPCSTR)&pFuncName->Name);
 
                    if (pMemLoad->api_GetModuleFileNameA) {
                        if (*(DWORD*)pFuncName->Name == 0x4D746547 && *(DWORD*)(pFuncName->Name + 4) == 0x6C75646F && *(DWORD*)(pFuncName->Name + 8) == 0x6C694665 && *(DWORD*)(pFuncName->Name + 12) == 0x6D614E65 && *(WORD*)(pFuncName->Name + 16) == 0x4165) {
                            *funcRef = (FARPROC)Proc_GetModulFileNameA;
                        }
                    }
                    if (pMemLoad->api_GetModuleFileNameW) {
                        if (*(DWORD*)pFuncName->Name == 0x4D746547 && *(DWORD*)(pFuncName->Name + 4) == 0x6C75646F && *(DWORD*)(pFuncName->Name + 8) == 0x6C694665 && *(DWORD*)(pFuncName->Name + 12) == 0x6D614E65 && *(WORD*)(pFuncName->Name + 16) == 0x5765) {
                            *funcRef = (FARPROC)Proc_GetModulFileNameW;
                        }
                    }
                }
                if (*funcRef == 0 && pMemLoad->api_MessageBoxA) {
                    pMemLoad->api_MessageBoxA(NULL, (char*)(InitBase + ImportAddr->Name), ((PIMAGE_IMPORT_BY_NAME)(*thunkRef + InitBase))->Name, MB_ICONASTERISK);
                }
            }
        }
    }
 
    //  修复重定位
    DWORD Value = InitBase - pNtHeader->OptionalHeader.ImageBase;
 
    if (pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0)
    {
        PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)((DWORD)InitBase + pDataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        while (relocation->VirtualAddress > 0)
        {
            BYTE* dest = (PBYTE)((DWORD)InitBase + relocation->VirtualAddress);
            WORD* relInfo = (PWORD)((DWORD)relocation + sizeof(IMAGE_BASE_RELOCATION));
            for (int i = 0; i < ((relocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2); ++i, ++relInfo)
            {
                DWORD* patchAddrHL;
                int type, offset;
 
                //the upper 4 bits define the type of relocation
                type = *relInfo >> 12;
                //the lower 12 bits define the offset
                offset = *relInfo & 0xFFF;
 
                switch (type)
                {
                case IMAGE_REL_BASED_ABSOLUTE:
                    //skip relocation
                    break;
                case IMAGE_REL_BASED_HIGHLOW:
                    //change comlete 32 bit address
                    patchAddrHL = (PDWORD)(dest + offset);
                    *patchAddrHL += Value;
                    break;
                default:
                    break;
                }
            }
 
            //advance to next relocation block
            relocation = PIMAGE_BASE_RELOCATION((DWORD)relocation + relocation->SizeOfBlock);
        }
    }
    //  线程TLS回调处理
    unsigned char* codeBase = (unsigned char*)InitBase;
    PIMAGE_TLS_DIRECTORY tls;
    PIMAGE_TLS_CALLBACK* callback;
 
    tls = (PIMAGE_TLS_DIRECTORY)((DWORD)InitBase + pDataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress);
    //tls = (PIMAGE_TLS_DIRECTORY)(codeBase + directory->VirtualAddress);
    callback = (PIMAGE_TLS_CALLBACK*)tls->AddressOfCallBacks;
    if (callback) {
        while (*callback) {
            (*callback)((LPVOID)codeBase, DLL_PROCESS_ATTACH, NULL);
            callback++;
        }
    }
 
    //  运行
 
    ((_DllMain)(InitBase + pNtHeader->OptionalHeader.AddressOfEntryPoint))((HMODULE)InitBase, DLL_PROCESS_ATTACH, NULL);
 
    return 0;
}

DLL链接:https://wwb.lanzouw.com/ijop005o4udc


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-6-27 13:55 被大佬求关照编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 6
活跃值: (556)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有没有人啊。。。
2022-6-8 01:22
0
游客
登录 | 注册 方可回帖
返回
//