Skip to content

Commit

Permalink
Remove some old code, see rovo89#8
Browse files Browse the repository at this point in the history
  • Loading branch information
rovo89 committed Jun 27, 2012
1 parent ec68edd commit 7cdb3dd
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 274 deletions.
2 changes: 0 additions & 2 deletions app_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ class AppRuntime : public AndroidRuntime
sp<ProcessState> proc = ProcessState::self();
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();

xposedCallStaticVoidMethod(getJNIEnv(), "onZygoteInit");
}

virtual void onExit(int code)
Expand Down
269 changes: 0 additions & 269 deletions xposed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,34 +196,6 @@ bool xposedOnVmCreated(JNIEnv* env, const char* className) {
return true;
}

void xposedCallStaticVoidMethod(JNIEnv* env, const char* methodName) {
if (!keepLoadingXposed)
return;

::Thread* self = dvmThreadSelf();
ThreadStatus oldThreadStatus = self->status;
//LOGI("Calling %s in XposedBridge\n", methodName);
Method* methodId = (Method*)env->GetStaticMethodID(xposedClass, methodName, "()V");
if (methodId == NULL) {
LOGE("ERROR: could not find method %s.%s()\n", XPOSED_CLASS, methodName);
dvmLogExceptionStackTrace();
env->ExceptionClear();
dvmChangeStatus(self, oldThreadStatus);
return;
}

env->CallStaticVoidMethod(xposedClass, (jmethodID)methodId);
if (env->ExceptionCheck()) {
LOGE("ERROR: uncaught exception in method %s.%s():\n", XPOSED_CLASS, methodName);
dvmLogExceptionStackTrace();
env->ExceptionClear();
dvmChangeStatus(self, oldThreadStatus);
return;
}
dvmChangeStatus(self, oldThreadStatus);
}



////////////////////////////////////////////////////////////
// handling hooked methods / helpers
Expand Down Expand Up @@ -533,251 +505,10 @@ static jobject de_robv_android_xposed_XposedBridge_getStartClassName(JNIEnv* env
return env->NewStringUTF(startClassName);
}

int memcpyToProcess(pid_t pid, void* dest, const void* src, size_t n) {
long *d = (long*) dest;
long *s = (long*) src;

if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
LOGE("could not attach to process %d: %s", pid, strerror(errno));
return 1;
}

waitpid(pid, 0, 0);

for (uint i = 0; i < n / sizeof(long); i++) {
if (ptrace(PTRACE_POKETEXT, pid, d+i, (void*)s[i]) == -1) {
LOGE("could not write memory to process %d (%p): %s", pid, d+i, strerror(errno));
return 1;
}
}

if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
LOGE("could not detach from process %d: %s", pid, strerror(errno));
return 1;
}

return 0;
}

// code copied from bspatch (http://www.daemonology.net/bsdiff/) and adjusted for in-memory replacement
static off_t offtin(u_char *buf)
{
off_t y;

y=buf[7]&0x7F;
y=y*256;y+=buf[6];
y=y*256;y+=buf[5];
y=y*256;y+=buf[4];
y=y*256;y+=buf[3];
y=y*256;y+=buf[2];
y=y*256;y+=buf[1];
y=y*256;y+=buf[0];

if(buf[7]&0x80) y=-y;

return y;
}

/* main changes:
- patched code is written to memory instead of file
- patching memory of other processes is supported
- only the first x bytes are patched, were x=min(size in patch header,original size,libsize from memory map)
- it is no error when the target size is larger than x, patching simply stops after x bytes
*/
int patchNativeLibrary(const char* libname, const char* patchfile, pid_t pid, u_char* libbase, ssize_t libsize)
{
FILE * f, * cpf, * dpf, * epf;
BZFILE * cpfbz2, * dpfbz2, * epfbz2;
int cbz2err, dbz2err, ebz2err;
int fd;
ssize_t oldsize,newsize,orig_newsize;
ssize_t bzctrllen,bzdatalen;
u_char header[32],buf[8];
u_char *old, *newbytes;
off_t oldpos,newpos;
off_t ctrl[3];
off_t lenread;
off_t i;

/* Open patch file */
if ((f = fopen(patchfile, "r")) == NULL)
return 1;

/*
File format:
0 8 "BSDIFF40"
8 8 X
16 8 Y
24 8 sizeof(newfile)
32 X bzip2(control block)
32+X Y bzip2(diff block)
32+X+Y ??? bzip2(extra block)
with control block a set of triples (x,y,z) meaning "add x bytes
from oldfile to x bytes from the diff block; copy y bytes from the
extra block; seek forwards in oldfile by z bytes".
*/

/* Read header */
if (fread(header, 1, 32, f) < 32)
return 1;

/* Check for appropriate magic */
if (memcmp(header, "BSDIFF40", 8) != 0)
return 1;

/* Read lengths from header */
bzctrllen=offtin(header+8);
bzdatalen=offtin(header+16);
newsize=orig_newsize=offtin(header+24);
if((bzctrllen<0) || (bzdatalen<0) || (newsize<0))
return 1;

/* Close patch file and re-open it via libbzip2 at the right places */
if ((fclose(f))

|| ((cpf = fopen(patchfile, "r")) == NULL)
|| (fseeko(cpf, 32, SEEK_SET))
|| ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL)

|| ((dpf = fopen(patchfile, "r")) == NULL)
|| (fseeko(dpf, 32 + bzctrllen, SEEK_SET))
|| ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL)

|| ((epf = fopen(patchfile, "r")) == NULL)
|| (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET))
|| ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL))
return 1;


if(((fd=open(libname,O_RDONLY,0))<0) ||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
((old=(u_char*)malloc(oldsize+1))==NULL) ||
(lseek(fd,0,SEEK_SET)!=0) ||
(read(fd,old,oldsize)!=oldsize) ||
(close(fd)==-1))
return 1;

if (newsize > libsize)
newsize = libsize;

if ((newbytes=(u_char*)malloc(newsize+1))==NULL)
return 1;

memcpy(newbytes, old, newsize);

oldpos=0;newpos=0;
while(newpos<newsize) {
/* Read control data */
for(i=0;i<=2;i++) {
lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);
if ((lenread < 8) || ((cbz2err != BZ_OK) &&
(cbz2err != BZ_STREAM_END)))
return 1;
ctrl[i]=offtin(buf);
};

/* Sanity-check */
if(newpos+ctrl[0]>newsize)
ctrl[0] = newsize - newpos;

/* Read diff string */
lenread = BZ2_bzRead(&dbz2err, dpfbz2, newbytes+ newpos, ctrl[0]);
if ((lenread < ctrl[0]) ||
((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
return 1;

/* Add old data to diff string */
for(i=0;i<ctrl[0];i++)
if((oldpos+i>=0) && (oldpos+i<oldsize))
newbytes[newpos+i]+=old[oldpos+i];

/* Adjust pointers */
newpos+=ctrl[0];
oldpos+=ctrl[0];

/* Sanity-check */
if(newpos+ctrl[1]>newsize)
ctrl[1] = newsize - newpos;

/* Read extra string */
lenread = BZ2_bzRead(&ebz2err, epfbz2, newbytes + newpos, ctrl[1]);
if ((lenread < ctrl[1]) ||
((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
return 1;

/* Adjust pointers */
newpos+=ctrl[1];
oldpos+=ctrl[2];
};

/* Clean up the bzip2 reads */
BZ2_bzReadClose(&cbz2err, cpfbz2);
BZ2_bzReadClose(&dbz2err, dpfbz2);
BZ2_bzReadClose(&ebz2err, epfbz2);
if (fclose(cpf) || fclose(dpf) || fclose(epf))
return 1;

/* Write patched memory content */
if (pid == 0) {
void* pageStart = (void*)((int)libbase & ~(PAGESIZE-1));
mprotect(pageStart, newsize, PROT_READ | PROT_WRITE | PROT_EXEC);
memcpy(libbase, newbytes, newsize);
} else {
if (memcpyToProcess(pid, libbase, newbytes, newsize))
return 1;
}

free(newbytes);

return 0;
}
// end of bspatch code

static jboolean de_robv_android_xposed_XposedBridge_patchNativeLibrary(JNIEnv* env, jclass clazz, jstring library, jbyteArray patch, jint pid, jlong libBase, jlong libSize) {
int returncode = 0;
jbyte* patchBytes;
ssize_t written;
char tmpPath[256];
const char* libraryPath;
FILE* tmpFile = NULL;

ssize_t size = env->GetArrayLength(patch);
if (size == 0)
goto leave;

// write byte array to temporary file
strcpy(tmpPath, "/data/xposed/tmp/xposed.libpatch.XXXXXX");
tmpFile = fdopen(mkstemp(tmpPath), "w");
if (tmpFile == NULL) {
LOGE("Could not create a temporary file %s", tmpPath);
goto leave;
}

patchBytes = env->GetByteArrayElements(patch, NULL);
written = fwrite(patchBytes, 1, size, tmpFile);
if (written != size) {
LOGE("Could only write %d of %d bytes to %s in patchNativeLibrary", (int)written, (int)size, tmpPath);
fclose(tmpFile);
goto leave;
}
fclose(tmpFile);

env->ReleaseByteArrayElements(patch, patchBytes, 0);
libraryPath = env->GetStringUTFChars(library, NULL);
returncode = patchNativeLibrary(libraryPath, tmpPath, pid, (u_char*)libBase, (ssize_t)libSize);
env->ReleaseStringUTFChars(library, libraryPath);

leave:
unlink(tmpPath);
return returncode == 0;
}


static const JNINativeMethod xposedMethods[] = {
{"hookMethodNative", "(Ljava/lang/reflect/Member;)V", (void*)de_robv_android_xposed_XposedBridge_hookMethodNative},
{"invokeOriginalMethodNative", "(Ljava/lang/reflect/Member;[Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)de_robv_android_xposed_XposedBridge_invokeOriginalMethodNative},
{"getStartClassName", "()Ljava/lang/String;", (void*)de_robv_android_xposed_XposedBridge_getStartClassName},
{"patchNativeLibrary", "(Ljava/lang/String;[BIJJ)Z", (void*)de_robv_android_xposed_XposedBridge_patchNativeLibrary},
};

static const JNINativeMethod xresourcesMethods[] = {
Expand Down
4 changes: 1 addition & 3 deletions xposed.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace android {
#define XPOSED_CLASS "de/robv/android/xposed/XposedBridge"
#define XPOSED_CLASS_DOTS "de.robv.android.xposed.XposedBridge"
#define XRESOURCES_CLASS "android/content/res/XResources"
#define XPOSED_VERSION "1.7b6"
#define XPOSED_VERSION "1.7b7"

extern bool keepLoadingXposed;
typedef std::list<Method>::iterator XposedOriginalMethodsIt;
Expand All @@ -25,7 +25,6 @@ bool isXposedDisabled();
bool addXposedToClasspath(bool zygote);
bool maybeReplaceLibs(bool zygote);
bool xposedOnVmCreated(JNIEnv* env, const char* className);
void xposedCallStaticVoidMethod(JNIEnv* env, const char* methodName);

// handling hooked methods / helpers
static void xposedCallHandler(const u4* args, JValue* pResult, const Method* method, ::Thread* self);
Expand All @@ -39,7 +38,6 @@ static jobject de_robv_android_xposed_XposedBridge_invokeOriginalMethodNative(JN
jobjectArray params1, jclass returnType1, jobject thisObject1, jobjectArray args1);
static void android_content_res_XResources_rewriteXmlReferencesNative(JNIEnv* env, jclass clazz,
jint parserPtr, jobject origRes, jobject repRes);
static jboolean de_robv_android_xposed_XposedBridge_patchNativeLibrary(JNIEnv* env, jclass clazz, jstring library, jbyteArray patch, jint pid, jlong libBase, jlong libSize);
static int register_de_robv_android_xposed_XposedBridge(JNIEnv* env);
static int register_android_content_res_XResources(JNIEnv* env);
}
Expand Down

0 comments on commit 7cdb3dd

Please sign in to comment.