I am trying to identify private apis of Quartz framework. I have a list of bunch of private private APIs but don't have their signature.
I would like to put one of them on table for discussion, so that we can have idea of how to reverse engineer to find the correct signature.
void CGContextDrawImages(????);
I got it from following assembly
_CGContextDrawImages:
+0 0008986a 55 pushl %ebp
+1 0008986b 89e5 movl %esp,%ebp
+3 0008986d 57 pushl %edi
+4 0008986e 56 pushl %esi
+5 0008986f 53 pushl %ebx
+6 00089870 81ecbc010000 subl $0x000001bc,%esp
+12 00089876 e800000000 calll 0x0008987b
+17 0008987b 5b popl %ebx
+18 0008987c 8b4508 movl 0x08(%ebp),%eax
+21 0008987f 85c0 testl %eax,%eax
+23 00089881 740c je 0x0008988f
+25 00089883 8b4508 movl 0x08(%ebp),%eax
+28 00089886 81780854585443 cmpl $0x43545854,0x08(%eax)
+35 0008988d 7424 je 0x000898b3
+37 0008988f 8b5508 movl 0x08(%ebp),%edx
+40 00089892 89542408 movl %edx,0x08(%esp)
+44 00089896 8d836ce16f00 leal 0x006fe16c(%ebx),%eax
+50 0008989c 89442404 movl %eax,0x04(%esp)
+54 000898a0 8d8341ae6f00 leal 0x006fae41(%ebx),%eax
+60 000898a6 890424 movl %eax,(%esp)
+63 000898a9 e8816f0f00 calll _CGPostError
+68 000898ae e9c4120000 jmp 0x0008ab77
+73 000898b3 8b4510 movl 0x10(%ebp),%eax
+76 000898b6 85c0 testl %eax,%eax
+78 000898b8 0f84b9120000 je 0x0008ab77
+84 000898be 8b450c movl 0x0c(%ebp),%eax
+87 000898c1 85c0 testl %eax,%eax
+89 000898c3 0f84ae120000 je 0x0008ab77
+95 000898c9 8b7d18 movl 0x18(%ebp),%edi
+98 000898cc 85ff testl %edi,%edi
+100 000898ce 0f84a3120000 je 0x0008ab77
+106 000898d4 31f6 xorl %esi,%esi
+108 000898d6 31ff xorl %edi,%edi
+110 000898d8 8b4d10 movl 0x10(%ebp),%ecx
+113 000898db 8b04b1 movl (%ecx,%esi,4),%eax
+116 000898de 85c0 testl %eax,%eax
+118 000898e0 740d je 0x000898ef
+120 000898e2 47 incl %edi
+121 000898e3 890424 movl %eax,(%esp)
+124 000898e6 e82f61fbff calll 0x0003fa1a
+129 000898eb 85c0 testl %eax,%eax
+131 000898ed 7506 jne 0x000898f5
+133 000898ef 46 incl %esi
+134 000898f0 397518 cmpl %esi,0x18(%ebp)
+137 000898f3 75e3 jne 0x000898d8
+139 000898f5 85ff testl %edi,%edi
+141 000898f7 0f847a120000 je 0x0008ab77
+147 000898fd 397518 cmpl %esi,0x18(%ebp)
+150 00089900 7743 ja 0x00089945
+152 00089902 8b4518 movl 0x18(%ebp),%eax
+155 00089905 89442418 movl %eax,0x18(%esp)
+159 00089909 8b5514 movl 0x14(%ebp),%edx
+162 0008990c 89542414 movl %edx,0x14(%esp)
+166 00089910 8b4d10 movl 0x10(%ebp),%ecx
+169 00089913 894c2410 movl %ecx,0x10(%esp)
+173 00089917 8b450c movl 0x0c(%ebp),%eax
+176 0008991a 8944240c movl %eax,0x0c(%esp)
+180 0008991e 8b5508 movl 0x08(%ebp),%edx
+183 00089921 8b4234 movl 0x34(%edx),%eax
+186 00089924 89442408 movl %eax,0x08(%esp)
+190 00089928 8b423c movl 0x3c(%edx),%eax
+193 0008992b 89442404 movl %eax,0x04(%esp)
+197 0008992f 8b4218 movl 0x18(%edx),%eax
+200 00089932 890424 movl %eax,(%esp)
+203 00089935 e8c264ffff calll 0x0007fdfc
+208 0008993a 3dee030000 cmpl $0x000003ee,%eax
+213 0008993f 0f85b6110000 jne 0x0008aafb
+219 00089945 8b7514 movl 0x14(%ebp),%esi
+222 00089948 85f6 testl %esi,%esi
+224 0008994a 0f84c4110000 je 0x0008ab14
+230 00089950 8b5508 movl 0x08(%ebp),%edx
+233 00089953 8b4234 movl 0x34(%edx),%eax
+236 00089956 890424 movl %eax,(%esp)
+239 00089959 e883d7f9ff calll 0x000270e1
+244 0008995e 85c0 testl %eax,%eax
+246 00089960 0f9585bbfeffff setne 0xfffffebb(%ebp)
+253 00089967 8b83f1677600 movl 0x007667f1(%ebx),%eax
+259 0008996d f30f104004 movss 0x04(%eax),%xmm0
+264 00089972 f30f118504ffffff movss %xmm0,0xffffff04(%ebp)
+272 0008997a f30f1008 movss (%eax),%xmm1
+276 0008997e f30f118d00ffffff movss %xmm1,0xffffff00(%ebp)
+284 00089986 f30f104008 movss 0x08(%eax),%xmm0
+289 0008998b f30f1185f8feffff movss %xmm0,0xfffffef8(%ebp)
+297 00089993 f30f10480c movss 0x0c(%eax),%xmm1
+302 00089998 f30f118dfcfeffff movss %xmm1,0xfffffefc(%ebp)
+310 000899a0 eb1a jmp 0x000899bc
+312 000899a2 f30f108dfcfeffff movss 0xfffffefc(%ebp),%xmm1
+320 000899aa 0f2ec8 ucomiss %xmm0,%xmm1
+323 000899ad 7a06 jp 0x000899b5
+325 000899af 0f84c2110000 je 0x0008ab77
+331 000899b5 c685bbfeffff00 movb $0x00,0xfffffebb(%ebp)
+338 000899bc 8b4510 movl 0x10(%ebp),%eax
+341 000899bf 898524ffffff movl %eax,0xffffff24(%ebp)
+347 000899c5 8b7d0c movl 0x0c(%ebp),%edi
+350 000899c8 8b5514 movl 0x14(%ebp),%edx
+353 000899cb 899528ffffff movl %edx,0xffffff28(%ebp)
+359 000899d1 c7852cffffff00000000 movl $0x00000000,0xffffff2c(%ebp)
+369 000899db 8d4dc4 leal 0xc4(%ebp),%ecx
+372 000899de 898d94feffff movl %ecx,0xfffffe94(%ebp)
+378 000899e4 8b8524ffffff movl 0xffffff24(%ebp),%eax
+384 000899ea 8b08 movl (%eax),%ecx
+386 000899ec 85c9 testl %ecx,%ecx
+388 000899ee 0f84e1100000 je 0x0008aad5
+394 000899f4 0f57c0 xorps %xmm0,%xmm0
+397 000899f7 0f2e4708 ucomiss 0x08(%edi),%xmm0
+401 000899fb 7a06 jp 0x00089a03
+403 000899fd 0f84d2100000 je 0x0008aad5
+409 00089a03 0f2e470c ucomiss 0x0c(%edi),%xmm0
+413 00089a07 7a06 jp 0x00089a0f
+415 00089a09 0f84c6100000 je 0x0008aad5
+421 00089a0f 8b5514 movl 0x14(%ebp),%edx
+424 00089a12 85d2 testl %edx,%edx
+426 00089a14 754e jne 0x00089a64
+428 00089a16 f30f108504ffffff movss 0xffffff04(%ebp),%xmm0
+436 00089a1e f30f1145d8 movss %xmm0,0xd8(%ebp)
+441 00089a23 f30f108d00ffffff movss 0xffffff00(%ebp),%xmm1
+449 00089a2b f30f114dd4 movss %xmm1,0xd4(%ebp)
+454 00089a30 f30f1085f8feffff movss 0xfffffef8(%ebp),%xmm0
+462 00089a38 f30f1145dc movss %xmm0,0xdc(%ebp)
+467 00089a3d f30f108dfcfeffff movss 0xfffffefc(%ebp),%xmm1
+475 00089a45 f30f114de0 movss %xmm1,0xe0(%ebp)
+480 00089a4a 8b45d4 movl 0xd4(%ebp),%eax
+483 00089a4d 8945b4 movl %eax,0xb4(%ebp)
+486 00089a50 8b45d8 movl 0xd8(%ebp),%eax
+489 00089a53 8945b8 movl %eax,0xb8(%ebp)
+492 00089a56 8b45dc movl 0xdc(%ebp),%eax
+495 00089a59 8945bc movl %eax,0xbc(%ebp)
+498 00089a5c 8b45e0 movl 0xe0(%ebp),%eax
+501 00089a5f 8945c0 movl %eax,0xc0(%ebp)
+504 00089a62 eb49 jmp 0x00089aad
+506 00089a64 8b8528ffffff movl 0xffffff28(%ebp),%eax
+512 00089a6a 0f2e4008 ucomiss 0x08(%eax),%xmm0
+516 00089a6e 7a06 jp 0x00089a76
+518 00089a70 0f845f100000 je 0x0008aad5
+524 00089a76 0f2e400c ucomiss 0x0c(%eax),%xmm0
+528 00089a7a 7a06 jp 0x00089a82
+530 00089a7c 0f8453100000 je 0x0008aad5
+536 00089a82 8d55b4 leal 0xb4(%ebp),%edx
+539 00089a85 89c1 movl %eax,%ecx
+541 00089a87 8b00 movl (%eax),%eax
+543 00089a89 89442404 movl %eax,0x04(%esp)
+547 00089a8d 8b4104 movl 0x04(%ecx),%eax
+550 00089a90 89442408 movl %eax,0x08(%esp)
+554 00089a94 8b4108 movl 0x08(%ecx),%eax
+557 00089a97 8944240c movl %eax,0x0c(%esp)
+561 00089a9b 8b410c movl 0x0c(%ecx),%eax
+564 00089a9e 89442410 movl %eax,0x10(%esp)
+568 00089aa2 891424 movl %edx,(%esp)
+571 00089aa5 e8f751fbff calll 0x0003eca1
+576 00089aaa 83ec04 subl $0x04,%esp
+579 00089aad f30f1045c0 movss 0xc0(%ebp),%xmm0
+584 00089ab2 f30f118518ffffff movss %xmm0,0xffffff18(%ebp)
+592 00089aba f30f104dbc movss 0xbc(%ebp),%xmm1
+597 00089abf f30f118d14ffffff movss %xmm1,0xffffff14(%ebp)
+605 00089ac7 8b07 movl (%edi),%eax
+607 00089ac9 89442404 movl %eax,0x04(%esp)
+611 00089acd 8b4704 movl 0x04(%edi),%eax
+614 00089ad0 89442408 movl %eax,0x08(%esp)
+618 00089ad4 8b4708 movl 0x08(%edi),%eax
+621 00089ad7 8944240c movl %eax,0x0c(%esp)
+625 00089adb 8b470c movl 0x0c(%edi),%eax
+628 00089ade 89442410 movl %eax,0x10(%esp)
+632 00089ae2 8b8594feffff movl 0xfffffe94(%ebp),%eax
+638 00089ae8 890424 movl %eax,(%esp)
+641 00089aeb e8b151fbff calll 0x0003eca1
+646 00089af0 83ec04 subl $0x04,%esp
+649 00089af3 f30f1045c4 movss 0xc4(%ebp),%xmm0
+654 00089af8 f30f118508ffffff movss %xmm0,0xffffff08(%ebp)
+662 00089b00 8b75c8 movl 0xc8(%ebp),%esi
+665 00089b03 f30f104dd0 movss 0xd0(%ebp),%xmm1
+670 00089b08 f30f118d10ffffff movss %xmm1,0xffffff10(%ebp)
+678 00089b10 f30f1045cc movss 0xcc(%ebp),%xmm0
+683 00089b15 f30f11850cffffff movss %xmm0,0xffffff0c(%ebp)
+691 00089b1d f30f108518ffffff movss 0xffffff18(%ebp),%xmm0
+699 00089b25 f30f1145c0 movss %xmm0,0xc0(%ebp)
+704 00089b2a f30f108d14ffffff movss 0xffffff14(%ebp),%xmm1
+712 00089b32 f30f114dbc movss %xmm1,0xbc(%ebp)
+717 00089b37 8b45b4 movl 0xb4(%ebp),%eax
+720 00089b3a 89442410 movl %eax,0x10(%esp)
+724 00089b3e 8b45b8 movl 0xb8(%ebp),%eax
+727 00089b41 89442414 movl %eax,0x14(%esp)
+731 00089b45 8b45bc movl 0xbc(%ebp),%eax
+734 00089b48 89442418 movl %eax,0x18(%esp)
+738 00089b4c 8b45c0 movl 0xc0(%ebp),%eax
+741 00089b4f 8944241c movl %eax,0x1c(%esp)
+745 00089b53 8b45c4 movl 0xc4(%ebp),%eax
+748 00089b56 890424 movl %eax,(%esp)
+751 00089b59 8b45c8 movl 0xc8(%ebp),%eax
+754 00089b5c 89442404 movl %eax,0x04(%esp)
+758 00089b60 8b45cc movl 0xcc(%ebp),%eax
+761 00089b63 89442408 movl %eax,0x08(%esp)
+765 00089b67 8b45d0 movl 0xd0(%ebp),%eax
+768 00089b6a 8944240c movl %eax,0x0c(%esp)
+772 00089b6e e823faf7ff calll 0x00009596
+777 00089b73 84c0 testb %al,%al
+779 00089b75 7437 je 0x00089bae
+781 00089b77 8b9524ffffff movl 0xffffff24(%ebp),%edx
+787 00089b7d 8b02 movl (%edx),%eax
+789 00089b7f f30f108508ffffff movss 0xffffff08(%ebp),%xmm0
+797 00089b87 f30f1145c4 movss %xmm0,0xc4(%ebp)
+802 00089b8c 8975c8 movl %esi,0xc8(%ebp)
+805 00089b8f f30f108d10ffffff movss 0xffffff10(%ebp),%xmm1
+813 00089b97 f30f114dd0 movss %xmm1,0xd0(%ebp)
+818 00089b9c f30f10850cffffff movss 0xffffff0c(%ebp),%xmm0
+826 00089ba4 f30f1145cc movss %xmm0,0xcc(%ebp)
+831 00089ba9 e9fc0e0000 jmp 0x0008aaaa
+836 00089bae f30f108508ffffff movss 0xffffff08(%ebp),%xmm0
+844 00089bb6 f30f1145c4 movss %xmm0,0xc4(%ebp)
+849 00089bbb 8975c8 movl %esi,0xc8(%ebp)
+852 00089bbe f30f108d10ffffff movss 0xffffff10(%ebp),%xmm1
+860 00089bc6 f30f114dd0 movss %xmm1,0xd0(%ebp)
+865 00089bcb f30f10850cffffff movss 0xffffff0c(%ebp),%xmm0
+873 00089bd3 f30f1145cc movss %xmm0,0xcc(%ebp)
+878 00089bd8 f30f108d18ffffff movss 0xffffff18(%ebp),%xmm1
+886 00089be0 f30f114dc0 movss %xmm1,0xc0(%ebp)
+891 00089be5 f30f108514ffffff movss 0xffffff14(%ebp),%xmm0
+899 00089bed f30f1145bc movss %xmm0,0xbc(%ebp)
+904 00089bf2 8b45b4 movl 0xb4(%ebp),%eax
+907 00089bf5 89442410 movl %eax,0x10(%esp)
+911 00089bf9 8b45b8 movl 0xb8(%ebp),%eax
+914 00089bfc 89442414 movl %eax,0x14(%esp)
+918 00089c00 8b45bc movl 0xbc(%ebp),%eax
+921 00089c03 89442418 movl %eax,0x18(%esp)
+925 00089c07 8b45c0 movl 0xc0(%ebp),%eax
+928 00089c0a 8944241c movl %eax,0x1c(%esp)
+932 00089c0e 8b45c4 movl 0xc4(%ebp),%eax
+935 00089c11 890424 movl %eax,(%esp)
+938 00089c14 8b45c8 movl 0xc8(%ebp),%eax
+941 00089c17 89442404 movl %eax,0x04(%esp)
+945 00089c1b 8b45cc movl 0xcc(%ebp),%eax
+948 00089c1e 89442408 movl %eax,0x08(%esp)
+952 00089c22 8b45d0 movl 0xd0(%ebp),%eax
+955 00089c25 8944240c movl %eax,0x0c(%esp)
+959 00089c29 e81acaf9ff calll 0x00026648
+964 00089c2e 84c0 testb %al,%al
+966 00089c30 0f846d010000 je 0x00089da3
+972 00089c36 80bdbbfeffff00 cmpb $0x00,0xfffffebb(%ebp)
+979 00089c3d 0f8583000000 jne 0x00089cc6
+985 00089c43 8b4508 movl 0x08(%ebp),%eax
+988 00089c46 890424 movl %eax,(%esp)
+991 00089c49 e81aaff9ff calll 0x00024b68
+996 00089c4e f30f108518ffffff movss 0xffffff18(%ebp),%xmm0
+1004 00089c56 f30f1145c0 movss %xmm0,0xc0(%ebp)
+1009 00089c5b f30f108d14ffffff movss 0xffffff14(%ebp),%xmm1
+1017 00089c63 f30f114dbc movss %xmm1,0xbc(%ebp)
+1022 00089c68 8b45b4 movl 0xb4(%ebp),%eax
+1025 00089c6b 89442404 movl %eax,0x04(%esp)
+1029 00089c6f 8b45b8 movl 0xb8(%ebp),%eax
+1032 00089c72 89442408 movl %eax,0x08(%esp)
+1036 00089c76 8b45bc movl 0xbc(%ebp),%eax
+1039 00089c79 8944240c movl %eax,0x0c(%esp)
+1043 00089c7d 8b45c0 movl 0xc0(%ebp),%eax
+1046 00089c80 89442410 movl %eax,0x10(%esp)
+1050 00089c84 8b4508 movl 0x08(%ebp),%eax
+1053 00089c87 890424 movl %eax,(%esp)
+1056 00089c8a e8a75efaff calll 0x0002fb36
+1061 00089c8f 8b9524ffffff movl 0xffffff24(%ebp),%edx
+1067 00089c95 8b02 movl (%edx),%eax
+1069 00089c97 f30f108508ffffff movss 0xffffff08(%ebp),%xmm0
+1077 00089c9f f30f1145c4 movss %xmm0,0xc4(%ebp)
+1082 00089ca4 8975c8 movl %esi,0xc8(%ebp)
+1085 00089ca7 f30f108d10ffffff movss 0xffffff10(%ebp),%xmm1
08a486 8b4590 movl 0x90(%ebp),%eax ...
I dont expect an exact answer but a way to decode the signature. Any Idea/direction would also be useful to carry on with research.
Thank you for your time. I really appreciate.
Often, you can work from what you know towards what you don't. This is likely used to implement a public CoreGraphics API; if you can find a function with known parameters calling this, you can pretty readily work out the parameters of this function.
You can work out how many arguments the function has by looking at the arguments it pulls off the stack. For example:
+18 0008987c 8b4508 movl 0x08(%ebp),%eax
+21 0008987f 85c0 testl %eax,%eax
+23 00089881 740c je 0x0008988f
You can tell from this that the first argument is most likely a 32-bit value. It's being tested against zero. Since this is a CGContext
function, the first argument is almost certainly CGContextRef ctx
, so these three instructions correspond to:
if (NULL == ctx) goto L0;
where I have glossed 0x008988f with L0 in the assembly.
+25 00089883 8b4508 movl 0x08(%ebp),%eax
+28 00089886 81780854585443 cmpl $0x43545854,0x08(%eax)
+35 0008988d 7424 je 0x000898b3
if (0x43545854 == ((int *)ctx)[2]) goto L1;
And here we see a comparison of a structure member against some known value that's being special-cased. It could be a magic number to verify the validity of the context. The code at the target address might reveal why it's being treated special.
+37 0008988f 8b5508 movl 0x08(%ebp),%edx
+40 00089892 89542408 movl %edx,0x08(%esp)
void *f0 = *ctx;
This dereferences the context pointer. If it's an Obj-C object behind the scenes, then this will be the isa
pointer referencing an Obj-C class. If not, then the context is likely some other sort of structure, and the code has just grabbed out some data from the very start of the structure. Setting a breakpoint here and trying to print-object
the provided address should answer which of these is true. (I'm betting on the Obj-C object case.)
+44 00089896 8d836ce16f00 leal 0x006fe16c(%ebx),%eax
+50 0008989c 89442404 movl %eax,0x04(%esp)
+54 000898a0 8d8341ae6f00 leal 0x006fae41(%ebx),%eax
Too bad you stopped there. Looks like it's setting up for a function call: stick the arguments on the stack, then call through. You can see it grabbing some relocated addresses based on a known address from early in the function (which the function found via that nifty call/pop
trick it did during the prologue).
I recommend you grab a copy of otx
– grab and build the SVN version, as it can handle x86_64. This does some work upfront to help you understand the disassembly, as well as formatting the disassembly nicely into basic blocks.
Also pick up class-dump
. This examines the Obj-C segments of the binaries you run it on and dumps out Obj-C header files for all the classes, categories, and protocols found in the binary.
Running both of these on the binary you're interested in can give you a big leg up.
If you're willing to spring for it, IDA Pro is considered the best tool out there for reverse engineering. I have never used it, but I can see where it would be tremendously helpful.
Other resources:
One more thing: Apple is generally pretty regular in its naming of functions. A function like CGContextDrawImages
has two likely signatures, depending on how the images are passed:
/* CGImageRefs contained in a Core Foundation array. */
void CGContextDrawImages(CGContextRef ctx, CFArrayRef images);
/* CGImageRefs passed in a C array. */
void CGContextDrawImages(CGContextRef ctx, CGImageRef images[], size_t count);
There might also be a "where to draw this" CGRect
argument or array of arguments. But at least you're not completely in the dark about what the function prototype should be.
This is not an easy task and might require tools other than gdb. I read a couple interesting RE tutorials and even though they are not specific to OSX they still provide interesting insight and examples on deciphering function parameters:
Reversing (Undocumented) Windows API Functions
Secrets of Reverse Engineering: Appendix C - Deciphering Program Data
User contributions licensed under CC BY-SA 3.0