Skip to content

Commit 6d6a7ea

Browse files
authored
Merge pull request JLospinoso#4 from ccooper21/master
Addresses issue JLospinoso#3 by adding support for multiple "mshtml.dll" versions
2 parents d7b1ceb + ed95b78 commit 6d6a7ea

File tree

2 files changed

+83
-7
lines changed

2 files changed

+83
-7
lines changed

Gargoyle.vcxproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<ProjectGuid>{76CDDD0D-EA56-4AA9-9B94-41390A34AB23}</ProjectGuid>
1515
<Keyword>Win32Proj</Keyword>
1616
<RootNamespace>Gargoyle</RootNamespace>
17-
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
17+
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
1818
</PropertyGroup>
1919
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2020
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -73,6 +73,7 @@
7373
<Link>
7474
<SubSystem>Console</SubSystem>
7575
<GenerateDebugInformation>true</GenerateDebugInformation>
76+
<AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies>
7677
</Link>
7778
</ItemDefinitionGroup>
7879
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

main.cpp

+81-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ namespace {
1212
constexpr DWORD invocation_interval_ms = 15 * 1000;
1313
constexpr size_t stack_size = 0x10000;
1414

15+
struct VersionToOffset {
16+
WORD file_version[4];
17+
uint32_t relative_offset;
18+
};
19+
20+
VersionToOffset mshtml_gadget_offset_map[] = {
21+
{ 11, 0, 14393, 953, 0x003CBD4D },
22+
{ 0, 0, 0, 0, 0x006D55DD } // Provides the default ROP gadget offset (for Windows v8.1?)
23+
};
24+
1525
struct SetupConfiguration {
1626
uint32_t initialized;
1727
void* setup_address;
@@ -70,19 +80,84 @@ MyTuple allocate_pic(const string& filename) {
7080
return MyTuple(pic, pic_size);
7181
}
7282

83+
uint32_t get_mshtml_gadget_relative_offset(const char *mshtml_filename) {
84+
DWORD version_handle;
85+
auto version_info_size = GetFileVersionInfoSizeA(mshtml_filename, &version_handle);
86+
if (version_info_size == 0) throw runtime_error("[-] Couldn't GetFileVersionInfoSize: " + GetLastError());
87+
88+
LPSTR version_data = new char[version_info_size];
89+
auto result = GetFileVersionInfoA(mshtml_filename, version_handle, version_info_size, version_data);
90+
if (!result) {
91+
delete[] version_data;
92+
throw runtime_error("[-] Couldn't GetFileVersionInfo: " + GetLastError());
93+
}
94+
95+
LPBYTE version_info_buffer;
96+
UINT version_info_buffer_size;
97+
result = VerQueryValueA(version_data, "\\", (VOID FAR* FAR*)&version_info_buffer, &version_info_buffer_size);
98+
if (!result) {
99+
delete[] version_data;
100+
throw runtime_error("[-] Couldn't VerQueryValue: " + GetLastError());
101+
}
102+
103+
VS_FIXEDFILEINFO *version_info = (VS_FIXEDFILEINFO *)version_info_buffer;
104+
WORD unpacked_file_version_words[4] = {
105+
(version_info->dwFileVersionMS >> 16) & 0xffff,
106+
(version_info->dwFileVersionMS >> 0) & 0xffff,
107+
(version_info->dwFileVersionLS >> 16) & 0xffff,
108+
(version_info->dwFileVersionLS >> 0) & 0xffff };
109+
DWORDLONG unpacked_file_version = *(DWORDLONG *)unpacked_file_version_words;
110+
delete[] version_data;
111+
112+
printf("[ ] Found %s version %d.%d.%d.%d.\n",
113+
mshtml_filename,
114+
unpacked_file_version_words[0],
115+
unpacked_file_version_words[1],
116+
unpacked_file_version_words[2],
117+
unpacked_file_version_words[3]);
118+
119+
uint32_t relative_offset = 0;
120+
auto using_default = false;
121+
int entry_num = 0;
122+
while (relative_offset == 0) {
123+
VersionToOffset *version_entry = &mshtml_gadget_offset_map[entry_num];
124+
if (*(DWORDLONG *)version_entry->file_version == unpacked_file_version
125+
|| *(DWORDLONG *)version_entry->file_version == 0)
126+
relative_offset = version_entry->relative_offset;
127+
using_default = *(DWORDLONG *)version_entry->file_version == 0;
128+
++entry_num;
129+
}
130+
131+
if (using_default) {
132+
printf("[*] WARNING: Unrecognized version, so using default relative offset.\n");
133+
}
134+
printf("[ ] %s ROP gadget is at relative offset 0x%p.\n", mshtml_filename, (void *)relative_offset);
135+
136+
return relative_offset;
137+
}
138+
139+
void* get_mshtml_gadget() {
140+
LPCSTR mshtml_filename = "mshtml.dll";
141+
printf("[ ] Loading %s.\n", mshtml_filename);
142+
auto mshtml_gadget_offset = get_mshtml_gadget_relative_offset(mshtml_filename);
143+
auto mshtml_base = reinterpret_cast<uint8_t*>(LoadLibraryA(mshtml_filename));
144+
if (mshtml_base == 0) throw runtime_error("[-] Couldn't LoadLibrary: " + GetLastError());
145+
146+
printf("[+] Loaded %s into memory at 0x%p.\n", mshtml_filename, mshtml_base);
147+
return mshtml_base + mshtml_gadget_offset;
148+
}
149+
73150
void* get_gadget(bool use_mshtml, const string& gadget_pic_path) {
151+
void* memory;
74152
if (use_mshtml) {
75-
printf("[ ] Loading mshtml.dll.\n");
76-
auto mshtml_base = reinterpret_cast<uint8_t*>(LoadLibraryA("mshtml.dll"));
77-
printf("[+] Loaded mshtml.dll into memory at 0x%p.\n", mshtml_base);
78-
return mshtml_base + 7165405;
153+
memory = get_mshtml_gadget();
79154
} else {
80155
printf("[ ] Allocating memory for %s.\n", gadget_pic_path.c_str());
81-
void* memory; size_t size;
156+
size_t size;
82157
tie(memory, size) = allocate_pic(gadget_pic_path);
83158
printf("[ ] Allocated %u bytes for gadget PIC.\n", size);
84-
return memory;
85159
}
160+
return memory;
86161
}
87162

88163
void launch(const string& setup_pic_path, const string& gadget_pic_path) {

0 commit comments

Comments
 (0)