I am trying to understand the usage of calls to CC_MD5 in an iOS application.

From Apple's man page I can see that when it is called it requires 3 arguments:

extern unsigned char *
CC_MD5(const void *data, CC_LONG len, unsigned char *md);

where *md is a pointer to where the result will be stored and is also what will be returned.

When CC_MD5 is called I would like to be able to log the input data and the resulting hash and have tried using the following script with Frida, including different ways of printing the data at the return pointer:

Interceptor.attach(Module.findExportByName("/usr/lib/libSystem.B.dylib", "CC_MD5"), {
  onEnter: function(args) {
    console.log("[+] CC_MD5 called with *data: " + Memory.readCString(args[0], parseInt(args[1], 16)));
    console.log("[+]                    *len:  " + parseInt(args[1], 16));
    console.log("[+]                    *md:   " + args[2]);
  onLeave: function(retval) {
    console.log("[+] Resulting hash: " + Memory.readCString(ptr(retval),16));
    console.log("[+] Resulting hash: " + retval.readByteArray(16));
    console.log("[+] Resulting hash: " + retval.readCString(16));

I understand that it will not always be printable text that is passed to the function as the input data however am having problems actually reading the resulting hash. Below is an example of the output I am getting:

[+] CC_MD5 called with *data: MGCopyAnswerProductVersion
[+]                    *len:  26
[+]                    *md:   0x16f6d61f0
[+] Returning *md: 0x16f6d61f0
[+] Resulting hash: ��]vU
[+] Resulting hash: [object ArrayBuffer]
[+] Resulting hash: ��]vU

I don't know if I have misunderstood how CC_MD5 is called or what I should be able to do with Frida?

  • 1
    The result hash is always 16 byte binary data. If you want to print it convert it to hex or base64. An example script for dumping raw memory data is embedded in this python script: github.com/poxyran/misc/blob/master/…
    – Robert
    Commented Jul 12, 2021 at 10:00
  • Hi @Robert thanks for the info, that really helped me understand what it is returning better and by using the code from that link I can compare the hexdump to what I get when I run MD5 on the input data and see they are the same. Do you know if it is possible to format the output not to include the offset and ascii representation? I came across your comment here which I thought would help but the outpout is comepletely blank trying that.
    – Jon
    Commented Jul 12, 2021 at 15:48
  • 1
    The code you have linked to only works in an Android/Java environment and for Java baste arrays. You mean better check the code presented here: github.com/frida/frida/issues/329
    – Robert
    Commented Jul 12, 2021 at 20:26
  • Yes, thank you @Robert that turned out to be exactly what I wanted. Are you able to add something as an answer so I can accept it or should just add an example of the code I used?
    – Jon
    Commented Jul 13, 2021 at 8:58

1 Answer 1


The main problem of your code is that you expect the md parameter to be a string. In C the unsigned char * is not an indicator for a string. Instead it is often for storing binary data.

In this case md is also just a pointer where the MD5 functions stores it's 16 byte of binary data. If you want to print the content you have to encode it e.g. hexadecimal or base64.

For printing binary data you can use Frida's hexdump method.

Alternatively you can convert the binary data yourself to a hexadezimal string and format it based on your preferences:

var a = retval.readByteArray(16)
var b = new Uint8Array(a);
var str = "";

for(var i = 0; i < b.length; i++) {
    str += (b[i].toString(16) + " ");
console.log("[+] Resulting hash: " + str);

Source of the code snippet

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.