Use Ghidra To Reverse GenyMotion—Suggestion
GenyMotion is a very popular android emulator around the world,so we need to do something for it.I want to show you some ideas for reversing this software.
The methods outlined in this article are only suggestions,it’s not a real crack.and i’ll introduce some useful method for ghidra.
Now,let’s start.
1.Change The License About Register Time.
Open the ghidra reverse engineer,load the genymotion application in the path /Applications/Genymotion.app/Contents/MacOS/genymotion.You need open the diretory in finding,drag and drop the file to the ghidra’s windows.
Search the string ‘expire’. (Search —> For Strings)
The result is:
Take a look at string “License about to expire”
Right click to copy the address “10015f2b4” for further use.(Copy–>Copy Columns–>Location)
Click ‘g'(or Navigation –> Go To… ) go to the address we found.
Right click to show the reference to this address or this function to step over.(References –> Show References to…)
we’ll see it’s jump to a new address “1000317e8”
This address is in the function as below,you could analyse this function to complete something.
*******************************************************
* FUNCTION *
*******************************************************
undefined FUN_1000f6460()
undefined AL:1 <RETURN>
FUN_1000f6460 XREF[5]: FUN_1000f4c90:1000f4f33(c),
FUN_1000f51b0:1000f51b5(c),
FUN_1000f5510:1000f5519(c),
FUN_1000f6770:1000f67a9(c),
FUN_1000f68a0:1000f68bd(c)
1000f6460 55 PUSH RBP
1000f6461 48 89 e5 MOV RBP,RSP
1000f6464 41 57 PUSH R15
1000f6466 41 56 PUSH R14
1000f6468 53 PUSH RBX
1000f6469 48 83 ec SUB RSP,0x38
38
1000f646d 49 89 ff MOV R15,RDI
1000f6470 48 8d 5d LEA RBX,[RBP + -0x28]
d8
1000f6474 48 89 df MOV RDI,RBX
1000f6477 e8 f8 ea CALL __stubs::__ZN9QDateTime18currentDateTimeU undefined __ZN9QDateTime18cu
03 00
1000f647c 4d 69 77 IMUL R14,qword ptr [R15 + 0x58],0x3e8
58 e8 03
00 00
1000f6484 48 89 df MOV RDI,RBX
1000f6487 e8 0a f0 CALL __stubs::__ZNK9QDateTime17toMSecsSinceEpo undefined __ZNK9QDateTime17t
03 00
1000f648c 48 89 c3 MOV RBX,RAX
1000f648f 49 8d 7f LEA RDI,[R15 + 0x30]
30
1000f6493 e8 fe ef CALL __stubs::__ZNK9QDateTime17toMSecsSinceEpo undefined __ZNK9QDateTime17t
03 00
1000f6498 48 29 d8 SUB RAX,RBX
1000f649b 4c 01 f0 ADD RAX,R14
1000f649e 48 3d 87 CMP RAX,0x1387
13 00 00
1000f64a4 0f 8f b2 JG LAB_1000f655c
00 00 00
1000f64aa c7 45 b0 MOV dword ptr [RBP + -0x50],0x2
02 00 00
00
1000f64b1 c7 45 c4 MOV dword ptr [RBP + -0x3c],0x0
00 00 00
00
1000f64b8 48 c7 45 MOV qword ptr [RBP + -0x44],0x0
bc 00 00
00 00
1000f64c0 48 c7 45 MOV qword ptr [RBP + -0x4c],0x0
b4 00 00
00 00
1000f64c8 48 8d 05 LEA RAX,[s_default_10015e50f] = "default"
40 80 06
00
1000f64cf 48 89 45 MOV qword ptr [RBP + -0x38],RAX=>s_default_10 = "default"
c8
1000f64d3 48 8d 7d LEA RDI,[RBP + -0x30]
d0
1000f64d7 48 8d 75 LEA RSI,[RBP + -0x50]
b0
1000f64db e8 34 ed CALL __stubs::__ZNK14QMessageLogger5debugEv undefined __ZNK14QMessageLog
03 00
1000f64e0 4c 8b 75 MOV R14,qword ptr [RBP + -0x30]
d0
1000f64e4 48 8d 35 LEA RSI,[s_License_has_expired_100163e44] = "License has expired"
59 d9 06
00
1000f64eb 48 8d 7d LEA RDI,[RBP + -0x20]
e0
1000f64ef ba 13 00 MOV EDX,0x13
00 00
1000f64f4 e8 0d e9 CALL __stubs::__ZN7QString15fromUtf8_helperEPK undefined __ZN7QString15from
03 00
1000f64f9 48 8d 75 LEA RSI,[RBP + -0x20]
e0
1000f64fd 4c 89 f7 MOV RDI,R14
1000f6500 e8 99 e4 CALL __stubs::__ZN11QTextStreamlsERK7QString undefined __ZN11QTextStreaml
03 00
1000f6505 48 8b 7d MOV RDI,qword ptr [RBP + -0x20]
e0
1000f6509 8b 07 MOV EAX,dword ptr [RDI]
1000f650b 83 f8 ff CMP EAX,-0x1
1000f650e 74 25 JZ LAB_1000f6535
1000f6510 85 c0 TEST EAX,EAX
1000f6512 74 12 JZ LAB_1000f6526
1000f6514 b8 ff ff MOV EAX,0xffffffff
ff ff
1000f6519 f0 LOCK
1000f651a 0f c1 07 XADD dword ptr [RDI],EAX
1000f651d 83 f8 01 CMP EAX,0x1
1000f6520 75 13 JNZ LAB_1000f6535
1000f6522 48 8b 7d MOV RDI,qword ptr [RBP + -0x20]
e0
We could use the same method to analyse the other string,such as “License has expired”,”license.expired”. and so on.
2.Change The Jump Condition
Track the string “License_has_expired”.
1. Address 100163e44
s_License_has_expired_100163e44 XREF[2]: FUN_1000f6460:1000f64e4(*),
FUN_10010a810:10010b949(*)
100163e44 4c 69 63 ds "License has expired"
65 6e 73
65 20 68
We could found two calls for this function.
2. Address 1000f64e4 in the function below,it’s caculate for expire time.
*******************************************************
* FUNCTION *
*******************************************************
undefined FUN_1000f6460()
undefined AL:1 <RETURN>
FUN_1000f6460 XREF[5]: FUN_1000f4c90:1000f4f33(c),
FUN_1000f51b0:1000f51b5(c),
FUN_1000f5510:1000f5519(c),
FUN_1000f6770:1000f67a9(c),
FUN_1000f68a0:1000f68bd(c)
1000f6460 55 PUSH RBP
1000f6461 48 89 e5 MOV RBP,RSP
1000f6464 41 57 PUSH R15
1000f6466 41 56 PUSH R14
1000f6468 53 PUSH RBX
1000f6469 48 83 ec SUB RSP,0x38
38
1000f646d 49 89 ff MOV R15,RDI
1000f6470 48 8d 5d LEA RBX,[RBP + -0x28]
d8
1000f6474 48 89 df MOV RDI,RBX
1000f6477 e8 f8 ea CALL __stubs::__ZN9QDateTime18currentDateTimeU undefined __ZN9QDateTime18cu
03 00
1000f647c 4d 69 77 IMUL R14,qword ptr [R15 + 0x58],0x3e8
58 e8 03
00 00
1000f6484 48 89 df MOV RDI,RBX
1000f6487 e8 0a f0 CALL __stubs::__ZNK9QDateTime17toMSecsSinceEpo undefined __ZNK9QDateTime17t
03 00
1000f648c 48 89 c3 MOV RBX,RAX
1000f648f 49 8d 7f LEA RDI,[R15 + 0x30]
30
1000f6493 e8 fe ef CALL __stubs::__ZNK9QDateTime17toMSecsSinceEpo undefined __ZNK9QDateTime17t
03 00
1000f6498 48 29 d8 SUB RAX,RBX
1000f649b 4c 01 f0 ADD RAX,R14
1000f649e 48 3d 87 CMP RAX,0x1387
13 00 00
1000f64a4 0f 8f b2 JG LAB_1000f655c
00 00 00
1000f64aa c7 45 b0 MOV dword ptr [RBP + -0x50],0x2
02 00 00
00
1000f64b1 c7 45 c4 MOV dword ptr [RBP + -0x3c],0x0
00 00 00
00
1000f64b8 48 c7 45 MOV qword ptr [RBP + -0x44],0x0
bc 00 00
00 00
1000f64c0 48 c7 45 MOV qword ptr [RBP + -0x4c],0x0
b4 00 00
00 00
1000f64c8 48 8d 05 LEA RAX,[s_default_10015e50f] = "default"
40 80 06
00
1000f64cf 48 89 45 MOV qword ptr [RBP + -0x38],RAX=>s_default_10 = "default"
c8
1000f64d3 48 8d 7d LEA RDI,[RBP + -0x30]
d0
1000f64d7 48 8d 75 LEA RSI,[RBP + -0x50]
b0
1000f64db e8 34 ed CALL __stubs::__ZNK14QMessageLogger5debugEv undefined __ZNK14QMessageLog
03 00
1000f64e0 4c 8b 75 MOV R14,qword ptr [RBP + -0x30]
d0
1000f64e4 48 8d 35 LEA RSI,[s_License_has_expired_100163e44] = "License has expired"
59 d9 06
00
1000f64eb 48 8d 7d LEA RDI,[RBP + -0x20]
e0
1000f64ef ba 13 00 MOV EDX,0x13
00 00
1000f64f4 e8 0d e9 CALL __stubs::__ZN7QString15fromUtf8_helperEPK undefined __ZN7QString15from
03 00
1000f64f9 48 8d 75 LEA RSI,[RBP + -0x20]
e0
1000f64fd 4c 89 f7 MOV RDI,R14
1000f6500 e8 99 e4 CALL __stubs::__ZN11QTextStreamlsERK7QString undefined __ZN11QTextStreaml
03 00
1000f6505 48 8b 7d MOV RDI,qword ptr [RBP + -0x20]
e0
1000f6509 8b 07 MOV EAX,dword ptr [RDI]
1000f650b 83 f8 ff CMP EAX,-0x1
1000f650e 74 25 JZ LAB_1000f6535
1000f6510 85 c0 TEST EAX,EAX
1000f6512 74 12 JZ LAB_1000f6526
1000f6514 b8 ff ff MOV EAX,0xffffffff
ff ff
1000f6519 f0 LOCK
1000f651a 0f c1 07 XADD dword ptr [RDI],EAX
1000f651d 83 f8 01 CMP EAX,0x1
1000f6520 75 13 JNZ LAB_1000f6535
1000f6522 48 8b 7d MOV RDI,qword ptr [RBP + -0x20]
e0
C code is below:
void FUN_1000f6460(long lParm1)
{
int iVar1;
long lVar2;
long lVar3;
long lVar4;
ulong uVar5;
ulong uVar6;
ulong uVar7;
undefined4 uStack88;
undefined8 uStack84;
undefined8 uStack76;
undefined4 uStack68;
char *pcStack64;
long lStack56;
undefined auStack48 [8];
int *piStack40;
__ZN9QDateTime18currentDateTimeUtcEv(auStack48);
lVar2 = *(long *)(lParm1 + 0x58);
lVar3 = __ZNK9QDateTime17toMSecsSinceEpochEv(auStack48);
lVar4 = __ZNK9QDateTime17toMSecsSinceEpochEv(lParm1 + 0x30);
uVar5 = (lVar4 – lVar3) + lVar2 * 1000;
if (4999 < (long)uVar5) { uVar6 = (uVar5 >> 0x3f) + uVar5 >> 1;
uVar7 = 0x7fffffff;
if ((long)uVar5 < 0xfffffffe) {
uVar7 = uVar6 & 0xffffffff;
}
__ZN6QTimer11setIntervalEi(lParm1 + 0x88,uVar7,0xfffffffe,uVar6);
__ZN6QTimer5startEv(lParm1 + 0x88);
goto LAB_1000f6590;
}
uStack88 = 2;
uStack68 = 0;
uStack76 = 0;
uStack84 = 0;
pcStack64 = “default”;
__ZNK14QMessageLogger5debugEv(&lStack56,&uStack88);
lVar2 = lStack56;
__ZN7QString15fromUtf8_helperEPKci(&piStack40,”License has expired”,0x13);
__ZN11QTextStreamlsERK7QString(lVar2,&piStack40);
if (piStack40 != -1) { if (piStack40 != 0) {
LOCK();
iVar1 = *piStack40;
*piStack40 = piStack40 + -1; if (iVar1 != 1) goto LAB_1000f6535; } __ZN10QArrayData10deallocateEPS_mm(piStack40,2,8); } LAB_1000f6535: if ((char *)(lStack56 + 0x20) != 0) {
__ZN11QTextStreamlsEc(lStack56,0x20);
}
__ZN6QDebugD1Ev(&lStack56);
FUN_100114240(lParm1);
LAB_1000f6590:
__ZN9QDateTimeD1Ev(auStack48);
return;
}
3. Address 1000f64a4:Change “JG” to “JL”,skip the “License_has_expired” function(You could use byte edit method too)
reference:http://faydoc.tripod.com/cpu/jg.htm
7C cb | JL rel8 | Jump short if less (SF<>OF) |
7F cb | JG rel8 | Jump short if greater (ZF=0 and SF=OF) |
1000f64a4 0f 8f b2 JG LAB_1000f655c
00 00 00
Right click this address,choose “Patch Instruction” command to change the code to edit mode.
Change ‘JG’ to ‘JL’,Continue to click ‘Enter’.
The other address in step 1,use the same method to change the jump condition.
4.Export the programme after changed.
Choose the ‘File’ menu,click ‘Export Program…’ command.
Set the export format to ‘Binary’.
Choose the ‘Output file’ path,click ‘ok’ button to complete.
All was done.