JNIEXPORT jint JNICALL hpatch(JNIEnv *env, jobject thiz, jstring oldFilePath, jstring diffFilePath, jstring newFilePath){ int argc = 4; char * argv[argc]; argv[0] = "hpatch"; argv[1] = (char*) (env->GetStringUTFChars(oldFilePath, 0)); argv[2] = (char*) (env->GetStringUTFChars(diffFilePath, 0)); argv[3] = (char*) (env->GetStringUTFChars(newFilePath, 0)); printf("old apk = %s \n", argv[1]); printf("patch = %s \n", argv[2]); printf("new apk = %s \n", argv[3]); int ret = applypatch(argc, argv); printf("patch result = %d ", ret); env->ReleaseStringUTFChars(oldFilePath, argv[1]); env->ReleaseStringUTFChars(newFilePath, argv[2]); env->ReleaseStringUTFChars(diffFilePath, argv[3]); // (*env)->DeleteLocalRef(env,argv[1]); // (*env)->DeleteLocalRef(env,argv[2]); // (*env)->DeleteLocalRef(env,argv[3]); return ret; }
int PatchMode(int argc, char** argv) { Value* bonus = NULL; if (argc >= 3 && strcmp(argv[1], "-b") == 0) { FileContents fc; if (LoadFileContents(argv[2], &fc, RETOUCH_DONT_MASK) != 0) { printf("failed to load bonus file %s\n", argv[2]); return 1; } bonus = malloc(sizeof(Value)); bonus->type = VAL_BLOB; bonus->size = fc.size; bonus->data = (char*)fc.data; argc -= 2; argv += 2; } if (argc < 6) { return 2; } char* endptr; size_t target_size = strtol(argv[4], &endptr, 10); if (target_size == 0 && endptr == argv[4]) { printf("can't parse \"%s\" as byte count\n\n", argv[4]); return 1; } char** sha1s; Value** patches; int num_patches; if (ParsePatchArgs(argc-5, argv+5, &sha1s, &patches, &num_patches) != 0) { printf("failed to parse patch args\n"); return 1; } int result = applypatch(argv[1], argv[2], argv[3], target_size, num_patches, sha1s, patches, bonus); int i; for (i = 0; i < num_patches; ++i) { Value* p = patches[i]; if (p != NULL) { free(p->data); free(p); } } if (bonus) { free(bonus->data); free(bonus); } free(sha1s); free(patches); return result; }
int main(int argc, char** argv) { int result = applypatch(argc, argv); if (result == 2) { fprintf(stderr, "usage: %s <src-file> <tgt-file> <tgt-sha1> <tgt-size> " "[<src-sha1>:<patch> ...]\n" " or %s -c <file> [<sha1> ...]\n" " or %s -s <bytes>\n" " or %s -l\n" "\n" "Filenames may be of the form\n" " MTD:<partition>:<len_1>:<sha1_1>:<len_2>:<sha1_2>:...\n" "to specify reading from or writing to an MTD partition.\n\n", argv[0], argv[0], argv[0], argv[0]); } return result; }
// apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1_1, patch_1, ...) Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 6 || (argc % 2) == 1) { return ErrorAbort(state, "%s(): expected at least 6 args and an " "even number, got %d", name, argc); } char* source_filename; char* target_filename; char* target_sha1; char* target_size_str; if (ReadArgs(state, argv, 4, &source_filename, &target_filename, &target_sha1, &target_size_str) < 0) { return NULL; } char* endptr; size_t target_size = strtol(target_size_str, &endptr, 10); if (target_size == 0 && endptr == target_size_str) { ErrorAbort(state, "%s(): can't parse \"%s\" as byte count", name, target_size_str); free(source_filename); free(target_filename); free(target_sha1); free(target_size_str); return NULL; } int patchcount = (argc-4) / 2; Value** patches = ReadValueVarArgs(state, argc-4, argv+4); int i; for (i = 0; i < patchcount; ++i) { if (patches[i*2]->type != VAL_STRING) { ErrorAbort(state, "%s(): sha-1 #%d is not string", name, i); break; } if (patches[i*2+1]->type != VAL_BLOB) { ErrorAbort(state, "%s(): patch #%d is not blob", name, i); break; } } if (i != patchcount) { for (i = 0; i < patchcount*2; ++i) { FreeValue(patches[i]); } free(patches); return NULL; } char** patch_sha_str = malloc(patchcount * sizeof(char*)); for (i = 0; i < patchcount; ++i) { patch_sha_str[i] = patches[i*2]->data; patches[i*2]->data = NULL; FreeValue(patches[i*2]); patches[i] = patches[i*2+1]; } int result = applypatch(source_filename, target_filename, target_sha1, target_size, patchcount, patch_sha_str, patches); for (i = 0; i < patchcount; ++i) { FreeValue(patches[i]); } free(patch_sha_str); free(patches); return StringValue(strdup(result == 0 ? "t" : "")); }
int main (int argc, char **argv) { if (argc<3) { fprintf (stderr,"Universal IPS Patcher - Copyright 2003 Steve Nickolas\n"); fprintf (stderr,"usage: uips source.ext patch.ips [outfile.ext]\n"); return -1; } sourcefile=fopen(argv[1],"r+b"); if (!sourcefile) { fprintf (stderr,"Source file "); perror(argv[1]); return -1; } if (argc>3) { f=fopen(argv[3],"wb"); } if(f) { fcopy(sourcefile, f); fclose(f); fclose(sourcefile); sourcefile=fopen(argv[3],"r+b"); strcpy(outname,argv[3]); } patchfile=fopen(argv[2],"rb"); if (!patchfile) { fprintf (stderr,"Patch file "); perror(argv[2]); return -1; } fseek(patchfile, 0, SEEK_END); patchsize = (int) ftell(patchfile); fseek(patchfile, 0, SEEK_SET); chunkarray = (char*)malloc(patchsize); if(!chunkarray) { fprintf (stderr,"Cannot allocate memory."); return -1; } isitanips(); printf ("Applying Patch '%s' to file '%s'...\n", argv[2], argv[1]); while (!feof(patchfile)) { getaddress(); getnumbytes(); if (numbytes) getchunk(); if (numbytes) applypatch(); else applyrle(); } closefiles(); /* avert warning */ return 40; }