crosire / blink

A tool which allows you to edit source code of any MSVC C++ project live at runtime

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Crash on PE import from WS2_32.dll

optimizedaway opened this issue · comments

Target process crashes with access violation during initial remote thread injection:

 	blink.exe!std::char_traits<char>::length(const char * const _First) Line 462	C++
 	blink.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign(const char * const _Ptr) Line 2676	C++
 	blink.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >(const char * const _Ptr) Line 2185	C++
 	blink.exe!std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,void *>::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,void *><char const (&)[1],void *,0>(const char[1] & _Val1, void * && _Val2) Line 173	C++
>	blink.exe!blink::application::run() Line 74	C++
 	blink.exe!remote_main(unsigned char * imagebase) Line 101	C++

I debugged target process. Symbols from dxgi.dll and d3d11 are properly initialized, but process fails on access to import->Name from WS2_32.dll, content of import_name_table[k].u1.AddressOfData looks very suspicious (0x800000000000006f). Addresses from other libraries are OK.

Output from debugger:

_symbols
{ size=0x0000000000000003 }
    [hash_function]: hash
    [key_eq]: equal_to
    [allocator]: allocator
    ["__ImageBase"]: ("__ImageBase", pbr.exe!0x00007ff65e6a0000)
    ["CreateDXGIFactory1"]: ("CreateDXGIFactory1", 0x00007ffa0210a200 {dxgi.dll!CreateDXGIFactory1(void)})
    ["D3D11CreateDevice"]: ("D3D11CreateDevice", 0x00007ffa001d5800 {d3d11.dll!D3D11CreateDevice(void)})
    [Raw View]: {...}

(const char *)(_image_base + import_directory_entries[0].Name)
0x00007ff65e84a104 "d3d11.dll"

(const IMAGE_THUNK_DATA *)(_image_base + import_directory_entries[0].Characteristics)
pbr.exe!0x00007ff65e849dd8 {u1={ForwarderString=0x00000000001aa0f0 Function=0x00000000001aa0f0 Ordinal=...} }
    u1: {ForwarderString=0x00000000001aa0f0 Function=0x00000000001aa0f0 Ordinal=0x00000000001aa0f0 ...}

(const char *)(_image_base + import_directory_entries[1].Name)
0x00007ff65e84a124 "dxgi.dll"

(const IMAGE_THUNK_DATA *)(_image_base + import_directory_entries[1].Characteristics)
pbr.exe!0x00007ff65e849de8 {u1={ForwarderString=0x00000000001aa10e Function=0x00000000001aa10e Ordinal=...} }
    u1: {ForwarderString=0x00000000001aa10e Function=0x00000000001aa10e Ordinal=0x00000000001aa10e ...}

(const char *)(_image_base + import_directory_entries[2].Name)
0x00007ff65e84a14c "WS2_32.dll"

(const IMAGE_THUNK_DATA *)(_image_base + import_directory_entries[2].Characteristics)
pbr.exe!0x00007ff65e849d90 {u1={ForwarderString=0x800000000000006f Function=0x800000000000006f Ordinal=...} }
    u1: {ForwarderString=0x800000000000006f Function=0x800000000000006f Ordinal=0x800000000000006f ...}

(const char *)(_image_base + import_directory_entries[3].Name)
0x00007ff65e84a35e "KERNEL32.dll"

(const IMAGE_THUNK_DATA *)(_image_base + import_directory_entries[4].Characteristics)
pbr.exe!0x00007ff65e849b88 {u1={ForwarderString=0x00000000001aa65e Function=0x00000000001aa65e Ordinal=...} }
    u1: {ForwarderString=0x00000000001aa65e Function=0x00000000001aa65e Ordinal=0x00000000001aa65e ...}

...

I "fixed" the problem by ignoring symbol addresses with highest bit set:

// Ignore symbol if MSB set in RVA, todo 32bit, ordinal lookup?
if ((import_name_table[k].u1.AddressOfData & 0x8000000000000000) == 0)
{
	const auto import = reinterpret_cast<const IMAGE_IMPORT_BY_NAME *>(_image_base + import_name_table[k].u1.AddressOfData);
	_symbols.insert({ import->Name, reinterpret_cast<void *>(import_address_table[k].u1.AddressOfData) });
}

I tried to dig through PE spec but didn't find anything useful. Maybe this is a lookup by ordinal number? Any ideas?

Win10 x64 Pro v1803 (17134.471), Windows SDK 10.0.17763.0

Yup, those are imports by ordinals. Not commonly used anymore, but ws2_32.dll is an exception. Will try and figure out a way to get from ordinals back to a symbol name (since that would be necessary to link in modified source code files which reference any functions from ws2_32.dll).