Index: branches/ErmaC/Enoch/i386/libsaio/xml.c =================================================================== --- branches/ErmaC/Enoch/i386/libsaio/xml.c (revision 2867) +++ branches/ErmaC/Enoch/i386/libsaio/xml.c (revision 2868) @@ -1462,3 +1462,299 @@ XMLFreeTag(tmpTag); return false; } +//========================================================================== +// Micky1979 +// XMLConvertTagPtrToXMLString +// convert back a TagPtr to a xml representation +// Here is still w/o header and footer +char *XMLConvertTagPtrToXMLString(TagPtr aDict, long parentType, int indent) +{ + indent ++; + // TODO check if we can use a buffer for the booter stuff already reserved somewhere + char *string = ""; + char *ind = ""; + for (int i = 0; i < indent; i++) + { + char *ind2 = malloc(strlen(ind) + strlen("\t") +1); + strcpy(ind2, ind); + ind2[strlen(ind)] = '\t'; + ind2[strlen(ind) +1] = '\0'; + ind = ind2; + } + unsigned long length = 0; + int count = XMLTagCount(aDict); + + while(count) + { + // parsing only supported tags + char *key = NULL; + TagPtr sub = NULL; + if (!XMLIsArray(aDict)) + { + key = XMLCastString(XMLGetKey(aDict, count)); + sub = XMLGetProperty(aDict, key); + } + else + { + key = ""; + sub = XMLGetElement( aDict, count-1); + } + + if(sub) + { + if(XMLIsData(sub)) + { + char *temp; + if (parentType == kTagTypeArray) + { + length = (strlen(ind) + + strlen(sub->string ? sub->string : "") + + strlen("") + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n", string, ind, sub->string ? sub->string : ""); + } else { + length = (strlen(ind) + + strlen(key) + + strlen("") + + strlen("\n") + + strlen(ind) + + strlen(sub->string ? sub->string : "") + + strlen("") + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n%s%s\n", + string, ind, key, ind, sub->string ? sub->string : ""); + } + + temp[strlen(string) + length] = '\0'; + string = temp; + } + else if(XMLIsString(sub)) + { + char *temp; + if (parentType == kTagTypeArray) + { + length = (strlen(ind) + + strlen("") + + strlen(XMLCastString(sub) ? XMLCastString(sub) : "") + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n", + string, ind, XMLCastString(sub) ? XMLCastString(sub) : ""); + } else { + length = (strlen(ind) + + strlen(key) + + strlen("") + + strlen("\n") + + strlen(ind) + + strlen("") + + strlen(XMLCastString(sub) ? XMLCastString(sub) : "") + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n%s%s\n", + string, ind, key, ind, XMLCastString(sub) ? XMLCastString(sub) : ""); + } + + temp[strlen(string) + length] = '\0'; + string = temp; + } + else if(XMLIsInteger(sub)) + { + // 'real' (float/dowble) cannot be parsed. only integers + int x = XMLCastInteger(sub); + char xBuf[snprintf( NULL, 0, "%d", x )]; + snprintf( xBuf, snprintf( NULL, 0, "%d", x ) +1, "%d", x ); + char *temp; + if (parentType == kTagTypeArray) + { + length = (strlen(ind) + + strlen("") + + sizeof(xBuf) + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n", string, ind, (char *)xBuf); + } else { + length = (strlen(ind) + + strlen(key) + + strlen("") + + strlen("\n") + + strlen(ind) + + strlen("") + + sizeof(xBuf) + + strlen("\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n%s%s\n", + string, ind, key, ind, (char *)xBuf); + } + + temp[strlen(string) + length] = '\0'; + string = temp; + } + else if(XMLIsBoolean(sub)) + { + char *temp; + int v = XMLCastBoolean(sub); + + if (parentType == kTagTypeArray) + { + length = (strlen(ind) + + strlen(v ? "\n" : "\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s", string, ind, v ? "\n" : "\n"); + } else { + length = (strlen(ind) + + strlen(key) + + strlen("") + + strlen("\n") + + strlen(ind) + + strlen(v ? "\n" : "\n") + + 1); + temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n%s%s", + string, ind, key, ind, v ? "\n" : "\n"); + } + + temp[strlen(string) + length] = '\0'; + string = temp; + } + else if (XMLIsDict(sub) || XMLIsArray(sub)) // its a contenitor.. + { + int subCount = XMLTagCount(sub); + char *otag = subCount <=0 ? "" : XMLIsDict(sub) ? "\n" : "\n"; + char *ctag = subCount <=0 ? XMLIsDict(sub) ? "\n" : + "\n" : XMLIsDict(sub) ? "\n" : "\n"; + char *dict = NULL; + dict = NULL; + dict = XMLConvertTagPtrToXMLString(sub, sub->type, indent); + + length = (strlen(ind) + + strlen(key) + + strlen("") + + strlen("\n") + + strlen(ind) + + strlen(otag) + + strlen(dict) + + strlen(ind) + + strlen(ctag) + + 1); + + char *temp = malloc(strlen(string) + length); + snprintf(temp, length+strlen(string), "%s%s%s\n%s%s%s%s%s\n", + string, ind, key, ind, otag, dict, ind, ctag); + + temp[strlen(string) + length] = '\0'; + string = temp; + } + } + count--; + } + + if(strlen(ind)) + { + free(ind); + } // not mallocated if "" + + return string; +} + +// XMLConvertTagPtrToPropertyList_v1 +// convert back a TagPtr to a xml representation +// with header and footer +char *XMLConvertTagPtrToPropertyList_v1(TagPtr aDict) +{ + if (!aDict) + { + return NULL; + } + + char *s = XMLConvertTagPtrToXMLString(aDict, aDict->type, 1); + + if (s == NULL) + { + return NULL; + } + + unsigned long length = ((strlen(kXMLv1) -1 /* -1 for %s included */) + + strlen(s) + + 1); + + char *propertyList = malloc(length); + snprintf(propertyList, length, kXMLv1, s); + + if (strlen(s)) + { + free(s); + } + + return (char *)propertyList; +} + +// XMLGenerateKextInjectorFromTag +// generate an full Info.plist to create a kext injector +// sDict should contains all the contents of IOKitPersonalities +// personalityName is a funcy name. Must not be a real kext name + +// OSBundleRequired should be the same of the real kext you want to hack (Root, Safe Boot, Network-Root etc.) +// can also be NULL or "" assuming the target kext does not have this key. +char * XMLGenerateKextInjectorFromTag(TagPtr aDict, char *personalityName, char *OSBundleRequired) +{ + if (!aDict || personalityName == NULL) + { + return NULL; + } + + char *IOKitPersonalities = XMLConvertTagPtrToXMLString(aDict, aDict->type, 1); + + if (IOKitPersonalities == NULL) + { + return NULL; + } + + char *OBRkey = OSBundleRequired == NULL ? "" : OSBundleRequired; + char *propertyList; + unsigned long length = 0; + + if (strlen(OBRkey)) + { + length = (strlen("\tOSBundleRequired\n\t") + + strlen(OBRkey) + + strlen("\n") + + 1); + char temp[length]; + snprintf(temp, length, "\tOSBundleRequired\n\t%s\n", OBRkey); + unsigned long mlength = ((strlen(kFakeInjectorKext) -8 /* %s x 8 */) + + strlen(personalityName) + + strlen(personalityName) + + strlen(IOKitPersonalities) + + length + + 1); + propertyList = malloc(mlength); + snprintf(propertyList, mlength, kFakeInjectorKext, personalityName, personalityName, IOKitPersonalities, temp); + } + else + { + unsigned long mlength = ((strlen(kFakeInjectorKext) -8 /* %s x 8 */) + + strlen(personalityName) + + strlen(personalityName) + + strlen(IOKitPersonalities) + + 1); + propertyList = malloc(mlength); + snprintf(propertyList, mlength, kFakeInjectorKext, personalityName, personalityName, IOKitPersonalities, ""); + } + + if (strlen(IOKitPersonalities)) + { + free(IOKitPersonalities); + } + + return propertyList; + +} Index: branches/ErmaC/Enoch/i386/libsaio/xml.h =================================================================== --- branches/ErmaC/Enoch/i386/libsaio/xml.h (revision 2867) +++ branches/ErmaC/Enoch/i386/libsaio/xml.h (revision 2868) @@ -72,6 +72,48 @@ #define kPropIOKitPersonalities ("IOKitPersonalities") #define kPropIONameMatch ("IONameMatch") +// Micky1979 +// kXMLv1 require one argument + +#define kXMLv1 "<\?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ +\n\ +\n\ +\n%s\n\ +\n\ +" + +// Micky1979 +// kFakeInjectorKext require 4 arguments (a generic name (used twice) + IOKitPersonalities + OSBundleRequired ("" if not needed)): +// name, name, IOKitPersonalities, OSBundleRequired +#define kFakeInjectorKext "<\?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ +\n\ +\n\ +\n\ + CFBundleDevelopmentRegion\n\ + English\n\ + CFBundleIdentifier\n\ + com.Enoch.plist.%s\n\ + CFBundleInfoDictionaryVersion\n\ + 6.0\n\ + CFBundleName\n\ + %s\n\ + CFBundlePackageType\n\ + KEXT\n\ + CFBundleSignature\n\ + \?\?\?\?\n\ + CFBundleVersion\n\ + 1.0.0\n\ + IOKitPersonalities\n\ + \n%s\ + \n%s\ +\n\ +\n" + +// Micky1979 following 3 funtions are to convert a TagPtr to a property list v1 and to create kexts injector +char *XMLConvertTagPtrToXMLString(TagPtr aDict, long parentType, int indent); +char *XMLConvertTagPtrToPropertyList_v1(TagPtr aDict); +char *XMLGenerateKextInjectorFromTag(TagPtr aDict, char *personalityName, char *OSBundleRequired); + extern long gImageFirstBootXAddr; extern long gImageLastKernelAddr;