0

Kinda... i have an DLL, that exports the only single function CreateInterface
From disassembled and then decompiled code:

int __cdecl CreateInterface(const char *a1, int a2)
{
//many crazy things
}

here it have a return type as int, but actually it's a pointer to some structure. from a main exe this lib is loaded and then used that way:

int (__stdcall *__cdecl Sys_GetFactory(int (__stdcall *hModule)()))()
{
  int (__stdcall *result)(); // eax@1

  result = hModule;
  if ( hModule )
    result = GetProcAddress(hModule, "CreateInterface");
  return result;
}

void some_funct()
{
    FARPROC net_interface =  Sys_GetFactory(pModule);
    int s_pClientNet = ((int (__cdecl *)(_DWORD, _DWORD))net_interface)("INetClient_003", 0);
}

and after being initialized it used that way:

 int result = (*(int (__stdcall **)(int, int, int, int))(*(_DWORD *)s_pClientNet + 60))(
                 login,
                 password,
                 mw_account_struct,
                 mw_account_struct_size);

so.. back to struct. Anyway to restore it, istead of calling needed functions by so crazy way? i mean (s_pClientNet + 60)

P.S. for sure i don't have dll sources, def file and etc. and don't have even idea what functions can be in target class / struct... the only thing i know it's some calls to that functions like that s_pClientNet + 60

Kosmo零
  • 4,001
  • 9
  • 45
  • 88
  • Some questions: How do you know that the returned type is a pointer to struct? Even though you know, wasn't it meant to be used that way (i.e. as an opaque type)? **WHY** do you need to get/know the struct content? – LeleDumbo Jun 12 '12 at 16:03
  • ehm, because the return value is used as pointer to class / struct to call functions like that s_pClientNet + 60, so s_pClientNet is pointer to begining, and 60 is offset to some function. – Kosmo零 Jun 12 '12 at 16:56
  • and i don't know all functions in that class / struct, i can see that +60? +48 and etc, who how many others is there? so i hoped maybe there is some way to rebuild struct fields – Kosmo零 Jun 12 '12 at 16:58

3 Answers3

3

Hmm, this looks like it might be a C++ class. There's an extra level of indirection, and I bet it's a vtable. s_pClientNet is definitely a pointer, but the +60 happens after dereferencing it. vpointers are usually the first element in the class, so that's more evidence. It's going to be basically impossible to recreate a C++ class that compiles to the same layout, unless you get really lucky. But you could manage some pieces manually.

typedef int(*login_fcn_t)(int, int, int, int);

struct ClientInterfaceVtable
{
    _DWORD reserved[60];
    login_fcn_t login_fcn;
};

struct ClientInterface
{
    ClientInterfaceVtable *vpointer;
    /// other fields
};

Now, after casting your s_pClientNet to a ClientInterface *, you should be able to invoke the login method via s_pClientNet->vpointer->login_fcn(login, etc.);

After you discover a few more fields, you could always try to create a polymorphic C++ class and see if you can push definitions around until you get a match, but that won't be portable.

Edit:

Hmm, I just realized the code isn't passing the this pointer. If I'm not completely wrong about the vtable, then that suggests this is a static method, perhaps a factory method of some sort.

Peter
  • 14,559
  • 35
  • 55
  • [Static method can't be virtual](https://stackoverflow.com/questions/7227236/can-we-have-a-virtual-static-method-c). – user202729 Jan 25 '21 at 09:52
1

It's rather difficult to impossible, AFAIK there's no guarantee regarding the layout and alignment of struct, so each compiler may layout the struct differently. Even the same compiler may have different data layouting through modifiers and/or compiler option.

LeleDumbo
  • 9,192
  • 4
  • 24
  • 38
1

I don't know of any way to automatically identify the struct, however if you are using IDA, you may be able to define the structure inside of IDA and then change the call signature to explicitly use it (changing the return value to that struct type and forcing re-analysis).

This may help you quicker analyse the structure and understand the program behavior, but ultimately it will be mostly manual analysis.

There may be some scripts for IDA/OllyDbg which can help with this, so it might be worth glancing over http://www.openrce.org/downloads/

stew
  • 491
  • 3
  • 7