I am attempting to implement an application-source integrity check in an iOS application to prevent anyone from modifying and re-installing the binary. I am currently using this tutorial (scroll down to Sample Implementation - application-source), however, the signature that the code generates seems to be different for every run on the app and I'd like to understand why.I had to force-compile the binary as 32-bit instead of 64 if this has anything to do with it, as the code below is built for 32 bit systems. The code from the tutorial is below int xyz(char* dst) {const struct mach_header * header;Dl_info dlinfo;if (dladdr(xyz, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) {    NSLog(@ Error: Could not resolve symbol xyz);    [NSThread exit];}while(1) {    header = dlinfo.dli_fbase;  // Pointer on the Mach-O header    struct load_command * cmd = (struct load_command *)(header + 1); // First load command    // Now iterate through load command    //to find __text section of __TEXT segment    for (uint64_t i = 0; cmd != NULL && i < header->ncmds; i++) {        if (cmd->cmd == LC_SEGMENT) {            // __TEXT load command is a LC_SEGMENT load command            struct segment_command * segment = (struct segment_command *)cmd;            if (!strcmp(segment->segname, __TEXT)) {                // Stop on __TEXT segment load command and go through sections                // to find __text section                struct section * section = (struct section *)(segment + 1);                for (uint32_t j = 0; section != NULL && j < segment->nsects; j++) {                    if (!strcmp(section->sectname, __text))                        break; //Stop on __text section load command                    section = (struct section *)(section + 1);                }                // Get here the __text section address, the __text section size                // and the virtual memory address so we can calculate                // a pointer on the __text section                uint32_t * textSectionAddr = (uint32_t *)section->addr;                uint32_t textSectionSize = section->size;                uint32_t * vmaddr = segment->vmaddr;                char * textSectionPtr = (char *)((int)header + (int)textSectionAddr - (int)vmaddr);                // Calculate the signature of the data,                // store the result in a string                // and compare to the original one                unsigned char digest[CC_MD5_DIGEST_LENGTH];                //CC_MD5(textSectionPtr, textSectionSize, digest);     // calculate the signature                for (int i = 0; i < sizeof(digest); i++)                    sprintf(dst + (2 * i), %02x, digest[i]);                //printf(%s, digest[i]);// fill signature                //ba391c93d02360da6e021166464b32                // return strcmp(originalSignature, signature) == 0;    // verify signatures match                return 0;            }        }        cmd = (struct load_command *)((uint8_t *)cmd + cmd->cmdsize);    }}}
Integrity Check signature is different on every run
ida;anti debugging;hopper