2011-04-06 16 views
5

क्रैश लॉग में आर्किटेक्चर (armv6/armv7) और सभी लोड मॉड्यूल के पहचानकर्ता के बारे में जानकारी के साथ "बाइनरी छवियां" अनुभाग शामिल है। रनटाइम पर इस जानकारी को कैसे निर्धारित करें? (कम से कम, केवल आवेदन निष्पादन योग्य के लिए)
एनएसबंडल में विधि निष्पादन योग्य आर्किटेक्चर हैं, लेकिन यह निर्धारित करने के लिए कि कौन सा आर्किटेक्चर चल रहा है?रनटाइम पर बाइनरी छवि आर्किटेक्चर कैसे निर्धारित करें?

उत्तर

14

लंबे उत्तर के लिए ठीक समय। एप्लिकेशन में डाइल्ड छवियों के मच हेडर में वह जानकारी होती है जिसे आप ढूंढ रहे हैं। मैंने एक उदाहरण जोड़ा है कि मैंने केवल काम करने के लिए परीक्षण किया है और कुछ भी नहीं तो मैं इसे सीधे उत्पादन कोड में पेस्ट करने की अनुशंसा नहीं करता। वर्तमान में लोड की गई सभी छवियों के लिए यह सभी मच हेडर प्राप्त करता है और क्रैश लॉग के बाइनरी छवियों अनुभाग के समान ही आउटपुट प्रिंट करता है। जिन तरीकों को मैं कॉल करता हूं वे थ्रेड सुरक्षित नहीं होते हैं। एक चीज जो मुझे याद आ रही है वह बाइनरी छवि का अंतिम पता है क्योंकि मुझे यह देखने के लिए परेशान नहीं था कि उसे कैसे ढूंढें।

main.m

#import <UIKit/UIKit.h> 

#include <string.h> 
#import <mach-o/loader.h> 
#import <mach-o/dyld.h> 
#import <mach-o/arch.h> 

void printImage(const struct mach_header *header) 
{ 
    uint8_t *header_ptr = (uint8_t*)header; 
    typedef struct load_command load_command; 

    const NXArchInfo *info = NXGetArchInfoFromCpuType(header->cputype, header->cpusubtype); 

    //Print the architecture ex. armv7 
    printf("%s ", info->name); 

    header_ptr += sizeof(struct mach_header); 
    load_command *command = (load_command*)header_ptr; 

    for(int i = 0; i < header->ncmds > 0; ++i) 
    { 
     if(command->cmd == LC_UUID) 
     { 
      struct uuid_command ucmd = *(struct uuid_command*)header_ptr; 

      CFUUIDRef cuuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *((CFUUIDBytes*)ucmd.uuid)); 
      CFStringRef suuid = CFUUIDCreateString(kCFAllocatorDefault, cuuid); 
      CFStringEncoding encoding = CFStringGetFastestEncoding(suuid); 

      //Print UUID 
      printf("<%s> ", CFStringGetCStringPtr(suuid, encoding)); 

      CFRelease(cuuid); 
      CFRelease(suuid); 

      break; 
     } 

     header_ptr += command->cmdsize; 
     command = (load_command*)header_ptr; 
    } 
} 

void printBinaryImages() 
{ 
    printf("Binary Images:\n"); 
    //Get count of all currently loaded DYLD 
    uint32_t count = _dyld_image_count(); 

    for(uint32_t i = 0; i < count; i++) 
    { 
     //Name of image (includes full path) 
     const char *dyld = _dyld_get_image_name(i); 

     //Get name of file 
     int slength = strlen(dyld); 

     int j; 
     for(j = slength - 1; j>= 0; --j) 
      if(dyld[j] == '/') break; 

     //strndup only available in iOS 4.3 
     char *name = strndup(dyld + ++j, slength - j); 
     printf("%s ", name); 
     free(name); 

     const struct mach_header *header = _dyld_get_image_header(i); 
     //print address range 
     printf("0x%X - ??? ", (uint32_t)header); 

     printImage(header); 

     //print file path 
     printf("%s\n", dyld); 
    } 
    printf("\n"); 
} 

int main(int argc, char *argv[]) 
{   
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    printBinaryImages(); 
    [pool release]; 
    return retVal; 
} 

उदाहरण आउटपुट:

Binary Images: 
TestBed 0x1000 - ??? i386 <E96D079C-E035-389D-AA12-71E968C76BFE> /Users/username/Library/Application Support/iPhone Simulator/4.3/Applications/6F64D9F8-9179-4E21-AE32-4D4604BE77E5/TestBed.app/TestBed 
UIKit 0x8000 - ??? i386 <72030911-362F-3E47-BAF3-ACD2CB6F88C0> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit 
Foundation 0x772000 - ??? i386 <EB718CBD-1D57-3D31-898D-7CFA9C172A46> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation 
CoreGraphics 0xA10000 - ??? i386 <D168A716-71F2-337A-AE0B-9DCF51AE9181> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics 
libSystem.dylib 0xCAA000 - ??? i386 <8DF0AFCD-FFA5-3049-88E2-7410F8398749> /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/usr/lib/libSystem.dylib 
... 
+0

जवाब के लिए धन्यवाद! चूंकि मुझे केवल एप्लिकेशन निष्पादन योग्य के लिए सीपीयू आर्किटेक्चर की आवश्यकता है, इसलिए मैंने dladdr (this_function) और फिर Dl_info.dli_fbase को mach_header के लिए पॉइंटर के रूप में उपयोग किया था। – michelnok

+0

@ जो, क्या आपको पता है कि _mh_execute_header (लगभग वैसे ही) से बंडल uuid प्राप्त करना ऐपस्टोर बाइनरी में काम करेगा? यह डेवलपर और विज्ञापन-निर्माण दोनों में काम करता है, लेकिन मैं निश्चित रूप से सुनिश्चित करना चाहता हूं। – Tertium

+0

@ टर्टियम मुझे यकीन नहीं है कि वह कार्य कहां स्थित है लेकिन यदि यह एक निजी ढांचे का हिस्सा है तो इसकी अनुमति नहीं दी जाएगी। – Joe

2

अकेले आर्किटेक्चर के बारे में त्वरित उत्तर के लिए जब आप अपना आवेदन बना रहे हैं तो आप कुछ प्रीप्रोसेसर परिभाषित कर सकते हैं कि वर्तमान एप्लिकेशन को निर्धारित करने के लिए आपका एप्लिकेशन बनाया गया है। सुनिश्चित करें कि आप पहले उपलब्ध शीर्ष के उच्चतम संस्करण की जांच करें क्योंकि प्रत्येक नया संस्करण सभी पुराने संस्करणों को परिभाषित करता है।

#if __arm__ 
#import <arm/arch.h> 

#ifdef __ARM_ARCH_6K__ 
//This is armv6 
#endif //__ARM_ARCH_6K__ 
#endif //__arm__ 
0

हम sysctl, sysctlbyname सिस्टम कॉल का उपयोग कर सकते हैं या सेट सिस्टम जानकारी के लिए।

नमूना कोड:

#import <sys/sysctl.h> 
#import <mach/machine.h> 

int32_t value = 0; 
size_t length = sizeof(value); 
sysctlbyname("hw.cputype", &value, &length, NULL, 0); 

if (value == CPU_TYPE_ARM64) { 
    // arm64 
} 
else if (value == CPU_TYPE_ARM) { 
    // armv7/armv7s 
} 
else if (value == CPU_TYPE_X86) { 
    // simulator 
} 

मैं सिर्फ "hw.cpusubtype" के लिए 2016 देखो पर सबसे आम मेहराब सूची अधिक detial प्राप्त करने के लिए, CPU_SUBTYPE_ARM_V6 तरह CPU_SUBTYPE_ARM_V7CPU_SUBTYPE_ARM_V7S

+0

यह डिवाइस के सीपीयू प्रकार को वापस कर देगा, जब सवाल वास्तुकला के बारे में है, बाइनरी मॉड्यूल के लिए संकलित किया गया था। तो, @ जो का जवाब सही था। – michelnok

संबंधित मुद्दे