Page 1 of 1

Magic Duels Reversing Fun

PostPosted: 14 Mar 2016, 14:34
by karmarobo
Hi there,

Today i randomly thought about Magic Duels and how it would be great to have it do what i want.
So i did the usual RE spiel,

1. open up the binary
2. see that its full of gibberish
3. dump the running process
4. Looks fine
5. Open it up in IDA
6. See that it uses LUA
7. Apply Lua flirt signatures
8. See how lua funcs are initialized
9. Rename them by script
10. Run the RTTI Scripts, see LOADS of stuff defined

Seems like this would be an easy reversing job so i check out the file formats AND WHAT DO I SEE

Theres a Duels.pdb in the Folder, i never had this before ...

So instead of meticulously defining structs, figuring out what the members do and renaming / typing them based on what i think it does i get listings like this

Code: Select all
struct __cppobj MTG::CPlayer : CLuaClass<MTG::CPlayer>, BZ::ClearMemory
{
  MTG::CDuel *mDuel;
  int mGlobal_index;
  unsigned int mUnique_ID;
  MTG::CTeam *mTeam;
...
};
Which is just crazy @_@

Re: Magic Duels Reversing Fun

PostPosted: 14 Mar 2016, 15:15
by karmarobo
Basically it turns

Code: Select all
int __thiscall sub_93EF80(int this)
{
  int v1; // esi@1
  _DWORD *v2; // edi@16
  int result; // eax@18

  v1 = this;
  *(_DWORD *)this = &MTG::CCardCharacteristics::`vftable'{for `MTG::CCardCharacteristics'};
  if ( !*(_BYTE *)(this + 352) && *(_DWORD *)(this + 348) )
    sub_A37850(*(_DWORD *)(this + 348));
  if ( !*(_BYTE *)(v1 + 360) && *(_DWORD *)(v1 + 356) )
    sub_49E970(*(_DWORD *)(v1 + 356));
  if ( !*(_BYTE *)(v1 + 368) && *(_DWORD *)(v1 + 364) )
    sub_49E9B0(*(_DWORD *)(v1 + 364));
  if ( !*(_BYTE *)(v1 + 396) && *(_DWORD *)(v1 + 392) )
    sub_49EA20(*(_DWORD *)(v1 + 392));
  if ( !*(_BYTE *)(v1 + 416) && *(_DWORD *)(v1 + 412) )
    sub_49EA20(*(_DWORD *)(v1 + 412));
  v2 = (_DWORD *)(v1 + 1044);
  sub_9C07E0(v1 + 1044);
  if ( *(_DWORD *)(v1 + 1044) )
  {
    sub_A377D0(*v2);
    *v2 = 0;
    *(_DWORD *)(v1 + 1048) = 0;
    *(_DWORD *)(v1 + 1052) = 0;
  }
  sub_49E670(v1 + 552);
  result = dword_1E41A14;
  *(_DWORD *)(v1 + 316) = &CLuaSimpleClass<MTG::CColour>::`vftable';
  if ( result )
  {
    sub_A6EBD0(*(_DWORD *)(v1 + 320), v1 + 316);
    result = dword_1E41A14;
  }
  *(_DWORD *)v1 = &CLuaSimpleClass<MTG::CCardCharacteristics>::`vftable';
  if ( result )
    result = sub_A6EBD0(*(_DWORD *)(v1 + 4), v1);
  return result;
}
into this
Code: Select all
int __thiscall sub_93EF80(MTG::CCardCharacteristics *this)
{
  MTG::CCardCharacteristics *v1; // esi@1
  MTG::CGuard ***v2; // edi@16
  int result; // eax@18

  v1 = this;
  this->vfptr = &MTG::CCardCharacteristics::`vftable'{for `MTG::CCardCharacteristics'};
  if ( !this->mBasic_data.card_type_is_inherited && this->mBasic_data.card_type )
    sub_A37850(this->mBasic_data.card_type);
  if ( !v1->mBasic_data.supertype_is_inherited && v1->mBasic_data.supertype )
    sub_49E970(v1->mBasic_data.supertype);
  if ( !v1->mBasic_data.sub_type_is_inherited && v1->mBasic_data.sub_type )
    sub_49E9B0(v1->mBasic_data.sub_type);
  if ( !v1->mBasic_data.abilities_are_inherited && v1->mBasic_data.abilities )
    sub_49EA20(v1->mBasic_data.abilities);
  if ( !v1->mBasic_data.resource_abilities_are_inherited && v1->mBasic_data.resource_abilities )
    sub_49EA20(v1->mBasic_data.resource_abilities);
  v2 = &v1->mGuards.mList._Myfirst;
  sub_9C07E0(&v1->mGuards);
  if ( v1->mGuards.mList._Myfirst )
  {
    sub_A377D0(*v2);
    *v2 = 0;
    v1->mGuards.mList._Mylast = 0;
    v1->mGuards.mList._Myend = 0;
  }
  sub_49E670(&v1->mMana_data);
  result = dword_1E41A14;
  v1->mBasic_data.colour.vfptr = &CLuaSimpleClass<MTG::CColour>::`vftable';
  if ( result )
  {
    sub_A6EBD0(v1->mBasic_data.colour.mL, &v1->mBasic_data.colour);
    result = dword_1E41A14;
  }
  v1->vfptr = &CLuaSimpleClass<MTG::CCardCharacteristics>::`vftable';
  if ( result )
    result = sub_A6EBD0(v1->mL, v1);
  return result;
}

Re: Magic Duels Reversing Fun

PostPosted: 08 Apr 2021, 03:19
by flatdragonfruit42
Hey, how did you do that.
I managed to get my hands on the .pdb but it the problem is that IDA can not find anything.
How did u manage to get the info from RTTI?