I need to locate the address of a function in a DLL at runtime which isn't exported. The DLL in question is vbe7.dll related to Visual Basic (and macros). The function is ___vbaInStr
, can be found in IDA if symbols are downloaded from Microsoft.
Locating it in IDA to get an offset is no biggie but I want to use it in Python and be able to locate it even if it's running on other machines. The reason being that I'm using winappdbg and need to place a breakpoint on the particular function to access the arguments pushed to the stack.
My theories so far have been:
- Find exported functions used close to a call to the targeted function and calculate the offset. Haven't tried it though.
- Find a instruction pattern around the call to the targeted function. This failed depending on the DLL version and compiler used.
- Look at the targeted function to locate the starting address, this failed for the same reason as above.
So getting the address of an exported function is easy but getting the address of a non-exported function? Target is .text:102242E3
.
.text:10224212 ; int __stdcall sub_10224212(int, LCID Locale, VARIANTARG *, VARIANTARG *pvarSrc, int)
.text:10224212 sub_10224212 proc near ; CODE XREF: sub_1000B164+859p
.text:10224212 ; rtcInStrChar+52p
.text:10224212
.text:10224212 arg_0 = dword ptr 8
.text:10224212 Locale = dword ptr 0Ch
.text:10224212 arg_8 = dword ptr 10h
.text:10224212 pvarSrc = dword ptr 14h
.text:10224212 arg_10 = dword ptr 18h
.text:10224212
.text:10224212 mov edi, edi
.text:10224214 push ebp
.text:10224215 mov ebp, esp
.text:10224217 push ebx
.text:10224218 push edi
.text:10224219 mov edi, [ebp+pvarSrc]
.text:1022421C push edi
.text:1022421D call rtcIsNull
.text:10224222 test ax, ax
.text:10224225 jnz loc_10224330
.text:1022422B mov ebx, [ebp+arg_8]
.text:1022422E push ebx
.text:1022422F call rtcIsNull
.text:10224234 test ax, ax
.text:10224237 jnz loc_10224330
.text:1022423D push esi
.text:1022423E push 8
.text:10224240 pop esi
.text:10224241 cmp [edi], si
.text:10224244 jnz short loc_1022424B
.text:10224246 mov edi, [edi+8]
.text:10224249 jmp short loc_10224261
.text:1022424B ; ---------------------------------------------------------------------------
.text:1022424B
.text:1022424B loc_1022424B: ; CODE XREF: sub_10224212+32j
.text:1022424B push edi ; pvarSrc
.text:1022424C call sub_1006D9C8
.text:10224251 mov edi, eax
.text:10224253 mov eax, esi
.text:10224255 mov word ptr pvarg.anonymous_0, ax ; jumptable 1000BE78 cases 56231,63056
.text:1022425B mov dword ptr pvarg.anonymous_0+8, edi ; jumptable 1000BE78 cases 56231,63056
.text:10224261
.text:10224261 loc_10224261: ; CODE XREF: sub_10224212+37j
.text:10224261 movzx eax, word ptr [ebx]
.text:10224264 cmp ax, si
.text:10224267 jnz short loc_1022426E
.text:10224269 mov eax, [ebx+8]
.text:1022426C jmp short loc_102242DB
.text:1022426E ; ---------------------------------------------------------------------------
.text:1022426E
.text:1022426E loc_1022426E: ; CODE XREF: sub_10224212+55j
.text:1022426E cmp word ptr pvarg.anonymous_0, si ; jumptable 1000BE78 cases 56231,63056
.text:10224275 jnz short loc_102242C7
.text:10224277 cmp ax, 9
.text:1022427B jnz short loc_102242C7
.text:1022427D xor eax, eax
.text:1022427F mov esi, offset pvarSrc
.text:10224284 push esi
.text:10224285 mov word ptr pvarg.anonymous_0, ax ; jumptable 1000BE78 cases 56231,63056
.text:1022428B push dword ptr [ebx+8]
.text:1022428E call sub_1022103A
.text:10224293 mov ebx, eax
.text:10224295 test ebx, ebx
.text:10224297 jz short loc_102242A6
.text:10224299 push edi ; bstrString
.text:1022429A call ds:__imp_SysFreeString ; jumptable 1000BE78 cases 171,16878,16935,30141,31177,32098,43703,61383,65216
.text:102242A0 push ebx
.text:102242A1 call sub_1005DCF1
.text:102242A6
.text:102242A6 loc_102242A6: ; CODE XREF: sub_10224212+85j
.text:102242A6 push 8
.text:102242A8 pop eax
.text:102242A9 push eax ; vt
.text:102242AA push esi ; pvarSrc
.text:102242AB push esi ; pvargDest
.text:102242AC mov word ptr pvarg.anonymous_0, ax ; jumptable 1000BE78 cases 56231,63056
.text:102242B2 mov dword ptr pvarg.anonymous_0+8, edi ; jumptable 1000BE78 cases 56231,63056
.text:102242B8 call sub_10082A4C
.text:102242BD mov eax, dword ptr pvarSrc.anonymous_0+8
.text:102242C2 push 8
.text:102242C4 pop esi
.text:102242C5 jmp short loc_102242DB
.text:102242C7 ; ---------------------------------------------------------------------------
.text:102242C7
.text:102242C7 loc_102242C7: ; CODE XREF: sub_10224212+63j
.text:102242C7 ; sub_10224212+69j
.text:102242C7 push ebx ; pvarSrc
.text:102242C8 call sub_1006D9C8
.text:102242CD mov ecx, esi
.text:102242CF mov word ptr pvarSrc.anonymous_0, cx
.text:102242D6 mov dword ptr pvarSrc.anonymous_0+8, eax
.text:102242DB
.text:102242DB loc_102242DB: ; CODE XREF: sub_10224212+5Aj
.text:102242DB ; sub_10224212+B3j
.text:102242DB push [ebp+arg_10] ; int
.text:102242DE push edi ; LPCWSTR
.text:102242DF push eax ; lpSrcStr
.text:102242E0 push [ebp+Locale] ; Locale
.text:102242E3 call sub_10083C60
.text:102242E8 mov edi, eax
.text:102242EA cmp word ptr pvarg.anonymous_0, si ; jumptable 1000BE78 cases 56231,63056
.text:102242F1 jnz short loc_10224307
.text:102242F3 push dword ptr pvarg.anonymous_0+8 ; bstrString