Find a reference for a string data reference in Ida Pro - dll

I would like to hack a dll.
My dll return an error message ( a return, and not a MessageBox).
I opened my dll in ida Pro.
I find my string data reference but i don't find xrefs from. When i try to find xrefs from i have the "Couldn't find any xrefs".
Anyone could help me please ? How finding reference please ? I would like to find the test which return this string in order to patch this dll. It's an ODBC Driver.
It's for a hack, not a crack ;)
I have the licence but i would like to change restriction in the odbc driver (the dll ).
Thanks a lot,

The string is probably referenced through an array of strings (the 3rd screenshot is probably this array). This would translate to something like this in assembly:
lea eax, StringArray ; load base of string array
mov ecx, StringIndex ; get string index in array
mov eax, [eax+ecx*4] ; eax (dest) = pointer to string
You probably just need to go up to the start of the string array to find a reference (reference to the first string on the array, hence a ref the array itself).

Related

Data of struct lose after passed from OCX to dll as a parameter of function

In my MFC ActiveX program, there is a calling of function offered by a dll file. And there is a struct type parameter in the function. The strange thing I met is after calling the function, the data in struct is not complete. I am a newer of ActiveX and DLL, and really can't understand how can this happened... The main codes are below:
The defination of struct:
typedef struct{
WORD m_protocol;
WORD m_playstart;
...
char url[128];
char username[MAX_USER_NAME_LEN+1];
char password[MAX_PASSWORD_LEN+1];
}CHANNEL_CLIENTINFO;
The ActiveX codes:
CHANNEL_CLIENTINFO channelInfo;
...
...
GSNET_ClientStart(&channelInfo);
The dll codes:
GSNET_ClientStart(CHANNEL_CLIENTINFO *m_pChaninfo)
{
...
...
}
Can anyone help me? Thanks all.
for more details:
In ActiveX program, before call the GSNET_ClientStart, I initialize the struct with some date. Such as the 'url':
sprintf(channelInfo.url, "192.168.121.122");
And after the calling, in dll function GSNET_ClientStart, I get out the url, it turns out to be "168.121.122", the "192." is missing.
I can make sure that I did't make any mistake in basic grammar.
There is a layout mismatch between the struct definitions in your two modules. It seems that the offset to the url member in your DLL has an offset of 4 more than the offset to that field in your ActiveX.
Make sure that the struct definitions match in both modules. Make sure that the compiler options relating to struct layout are the same in both modules.
I cannot give a definitive fix because there are so many ways in which this mismatch could occur, but for sure the root problem is a mismatch.

Get the address in ARM Inline assembly

The IAR compiler for ARM Cortex-M3 provides inline assembly. How can one store the address of a specific function to a location on the stack?
The C code would like this
void tick();
void bar()
{
int x;
// modify a value on stack
(&x)[4] = &tick;
}
While this works in general it is optimized away by the compiler in release build. I have tried to code it with inline assembly
void bar()
{
int x;
asm("ldr r0,%0" : : "i" (&tick));
asm("str r0,[sp+#0x10];
}
The ldr instruction is not accepted by the IAR compiler. The problem is that this instruction requires an addressing mode with a register and offset. The actual address of the function tick is store behind the function and the ldr instruction holds only the offset to the memory location the holds the actual address. The disassembly is similar like this:
ldr r0,??tick_address
str r0,[sp+#0x10]
bx lr ; return
??tick_address dd tick
How do I get the address of tick immediately to a register to use it for the stack manipulation?
GNU GCC inline assembly can do mere assignments via pseudo-empty asm() statements, like:
asm("" : "=r"(foo) : "0"(tick));
This tells the compiler:
The variable foo is to be taken from a register after the inline assembly block
The variable tick is to be passed in - in the same register (argument zero)
The actual choice of which register is to be used is completely left to the compiler.
The trick here are the output and input constraints - we just alias the (one and only) input to the output, and the compiler will, on its own, choose a suitable register, and generate the instructions necessary to load / store the respective variables before / after the "actual" inline assembly code. You could even do:
asm("" : "=r"(foo1), "=r"(foo2) : "0"(tick1) , "1"(tick2));
to do two "assignments" in a single inline assembly statement.
This compiler-generated "set the inputs, retrieve the outputs" code generation happens even if the actual inline assembly is empty (as here).
Another example: Say you want to read the current program counter - the PC register. You can do that on ARM via two different inline assembly statements:
asm("" : "=pc"(foo));
asm("mov %0, PC" : "=r"(foo));
This is not 100% identical; in the second case, the compiler knows that whatever register it wants to see foo in after the asm, it'll find it there. In the former, the compiler knows that were it to use foo after the statement, it needs to retrieve it from PC. The difference between the two would be if you did:
uintptr_t *val;
uintptr_t foo;
asm("" : "=pc"(foo));
*val = foo;
In this case, the compiler can possibly identify that this can be turned into a single str [R...], PC because it knows foo is in pc after the asm. Were you to write this via
asm("mov %0, PC" : "=r"(foo));
*val = foo;
the compiler would be forced to create (assuming it chooses R0 / R1 for foo/val):
MOV R0, PC
STR [R1], R0
The documentation for this behaviour is largely in the "Extended ASM" section of the GCC manuals, see the example for the contrived combine instruction.
There is no assignment the variable x in your code, therefore it's value is undefined and setting foo to an undefined value isn't required to change foo.
You need to assign the value to the variable, not to some memory location you assume the compiler use to implement it.

How do I link with FreePascal a NASM program calling a DLL?

Problem
I have a function "bob" written in assembler (nasm), which makes use of functions in kernel32.dll. And I have a program in FreePascal, that calls "bob".
I use nasm with:
nasm -fwin32 bob.asm
In FreePascal I declare:
{$link bob.obj}
function bob(s:pchar):longint; stdcall; external name 'bob';
But I get an error when I compile with fpc, telling it doesn't find GetStdHandle and WriteConsoleA (without #n suffix), which are declared extern in bob.asm. I would like to tell fpc to look for them in kernel32.dll, or in an adequate import library.
However, when I use the same function in pure assembly program, it works fine with nasm and golink. And when I don't call DLL functions, I can link with FreePascal with no trouble.
How can I link kernel32 functions with FreePascal, so that assembly functions "see" them ?
A Solution
Given by BeniBela. I change names so that things are easy to follow.
program dlltest;
function WindowsGetStdHandle(n: longint): longint; stdcall;
external 'kernel32.dll' name 'GetStdHandle';
{$asmmode intel}
procedure WrapperGetStdHandle; assembler; public name 'AliasGetStdHandle';
asm
jmp WindowsGetStdHandle
end;
{$link myget.obj}
function AsmGetStdHandle(n: longint): longint; stdcall;
external name 'gethandle';
const STDOUT = -11;
begin
writeln(AsmGetStdHandle(STDOUT));
writeln(WindowsGetStdHandle(STDOUT));
end.
With this in assembly, in myget.asm:
section .text
extern AliasGetStdHandle
global gethandle
gethandle:
mov eax, [esp+4]
push eax
call AliasGetStdHandle
ret 4
WindowsGetStdHandle is another name for GetStdHandle in kernel32.dll.
WrapperGetStdHandle only jump to the preceding, it's here for the alias or public name capability : we give it the name AliasGetStdHandle for external objects. This is the important part, the function get visible to the assembly program.
AsmGetStdHandle is the name in FreePascal of the assembly function gethandle. It calls WrapperStdHandle (nicknamed AliasGetStdHandle), which jumps to WindowsGetStdHandle, the DLL function.
And we are done, now the assembly program can be linked, without changing anything in it. All the renaming machinery is done in the pascal program calling it.
The only drawback: the need for a wrapper function, but it's not overpriced for a fine control of names.
Another solution
If kernel32.dll is not specified in declaration of WindowsGetStdHandle, but with {$linklib kernel32}, then the symbol gets visible in object files linked in the pascal program. However, it seems the $linklib directive alone is not enough, one still has to declare in pascal some function refering to it
program dlltest;
{$linklib kernel32}
function WindowsGetStdHandle(n: longint): longint; stdcall;
external name 'GetStdHandle';
{$link myget.obj}
function AsmGetStdHandle(n: longint): longint; stdcall;
external name 'gethandle';
const STDOUT = -11;
begin
writeln(AsmGetStdHandle(STDOUT));
writeln(WindowsGetStdHandle(STDOUT));
end.
With the following assembly program. AliasGetStdHandle is replaced with GetStdHandle, which now points directly to kernel32 function.
section .text
extern GetStdHandle
global gethandle
gethandle:
mov eax, [esp+4]
push eax
call GetStdHandle
ret 4
But this only works when using the external linker (gnu ld), with command
fpc -Xe dlltest.pas
When omitting opton '-Xe', fpc gives the following error
Free Pascal Compiler version 2.6.0 [2011/12/25] for i386
Copyright (c) 1993-2011 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling dlltest.pas
Linking dlltest.exe
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_dir_kernel32.dll
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_names_kernel32.dll
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_fixup_kernel32.dll
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_dll_kernel32.dll
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_names_end_kernel32.dll
dlltest.pas(17,1) Error: Asm: Duplicate label __imp_fixup_end_kernel32.dll
dlltest.pas(17,1) Fatal: There were 6 errors compiling module, stopping
Fatal: Compilation aborted
I do not know how to fix the linking issue directly, but you could declare public wrapper functions that export these functions from the Pascal source.
E.g.:
{$ASMMODE INTEL}
procedure WrapperGetStdHandle; assembler; public; alias: '_GetStdHandle#4';
asm jmp GetStdHandle end;
procedure WrapperWriteConsoleA; assembler; public; alias: '_WriteConsoleA#20';
asm jmp WriteConsoleA end;
I suspect there is some import library automatically linked by nasm them for use with nasm code, and probably you need to link the relevant stubs from that library too.
amended:
It might be a problem with smart linking. As said FPC generates import stubs on the fly, but only when needed. Because the Windows unit (that holds all core WINAPI calls) is so large, smart linking (only adding what you use) is activated for it. (there are other reasons too)
The NASM originated obj is outside FPC's control, so the relevant functions are not generated for it.
If that is the case, BeniBela's code might work because it forces a reference from FPC code, linking in the symbols. This is speculation though, it might be something with the decoration too, or something with the leading underscore.
Testing that is simple, use the functions from pascal code without the declarations from Benibela.
Btw, FPC's default is NOT stdcall, so BenBela's functions should probably get a stdcall modifier

Is it possible in IDA Pro to make a struct field offset to vtable which is defined in .data segment?

Here is what I want to achieve. I identified a class which I defined as a struct to store class data. One of the methods of the class uses class-field as if it's pointer to vtable.
int __thiscall SignOn(struc_4 *this)
{
v1 = this;
if ( !v1->vtable_40194AE0 )
return E_UNEXPECTED;
v1->field_3E8 = 0;
if ( !sub_686F7193(v1) )
return (*(*v1->vtable_40194AE0 + 12))(v1->vtable_40194AE0, 0, 0); // sub_40128EEE
}
As you can see it calls 3rd function from vtable. In run-time I identified that vtable_40194AE0 points to array in .data section which looks like this
off_40194AE0 dd offset InternalQueryInterface
dd offset AddRef
dd offset Release
dd offset sub_40128EEE ; 3
dd offset sub_40128F8C
dd offset sub_4012C2E2 ; 5
Is there a way to tell somehow IDA that vtable_40194AE0 always points to vtable at 0x40194AE0 so given call in the pseudo-code will look like
return vtable_40194AE0->sub_40128EEE(v1->vtable_40194AE0, 0, 0);
?
I tried to set vtable_40194AE0 of the structure to be "user-defined offset" but it doesn't help :(
Thanks a lot !
Of course, it's possible!
Open "Structures" window, find your class struct (struc_4 in your case) and open it (if it was collapsed). Select vtable field (it should be at first place), press Y and enter the type declaration as a pointer to vtable struct in opened window (vtable_40194AE0* in your case). That's it.
You can make a structure representing the vtable, declare C types of its fields with Y (to be typed function pointers) and make the offset in the call [ecx+12] an offset of that structure with T. This way, IDA will recognize the call's arguments.
In the structure representing the class, set the type of vtable field to be a pointer to the vtable structure, then if you're lucky, decompiler will put things together and put the vtable structure field name into the call instead of an offset.
To my knowledge, no. IDA structs are merely provided to make the process of visualizing disassembled data easier. The most you can do is comment the call site to identify the actual virtual function being called.

ComBSTR assignment

I'm confused about COM string assignments. Which of the following string assignment is correct. Why?
CComBSTR str;
.
.
Obj->str = L"" //Option1
OR should it be
Obj->str = CComBSTR(L"") //Option2
What is the reason
A real BSTR is:
temporarily allocated from the COM heap (via SysAllocString() and family)
a data structure in which the string data is preceded by its length, stored in a 32-bit value.
passed as a pointer to the fifth byte of that data structure, where the string data resides.
See the documentation:
MSDN: BSTR
Most functions which accept a BSTR will not crash when passed a BSTR created the simple assignment. This leads to confusion as people observe what seems to be working code from which they infer that a BSTR can be initialized just like any WCHAR *. That inference is incorrect.
Only real BSTRs can be passed to OLE Automation interfaces.
By using the CComBSTR() constructor, which calls SysAllocString(), your code will create a real BSTR. The CComBSTR() destructor will take care of returning the allocated storage to the system via SysFreeString().
If you pass the CComBSTR() to an API which takes ownership, be sure to call the .Detach() method to ensure the BSTR is not freed. BSTRs are not reference counted (unlike COM objects, which are), and therefore an attempt to free a BSTR more than once will crash.
If you use str = CComBSTR(L"") you use the constructor:
CComBSTR( LPCSTR pSrc );
If you use str = L"" you use the assignment operator:
CComBSTR& operator =(LPCSTR pSrc);
They both would initialize the CComBSTR object correctly.
Personally, I'd prefer option 1, because that doesn't require constructing a new CComBSTR object. (Whether their code does so behind the scenes is a different story, of course.)
Option 1 is preferred because it only does one allocation for the string where as option 2 does 2 (not withstanding the creation of a new temporary object for no particular reason). Unlike the bstr_t type in VC++ the ATL one does not do referenced counted strings so it will copy the entire string across.