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;