diff --git a/offset-extract/offset-extract.sh b/offset-extract/offset-extract.sh new file mode 100644 index 0000000..2b371a3 --- /dev/null +++ b/offset-extract/offset-extract.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +if [ $# = 0 ]; then + echo "Usage: $0 [optional mysqld symbols]" + echo "Will extract offsets from mysqld. Requires gdb and mysqld symbols." + exit 1 +fi + +#extract the version + +FULL_MYVER=`$1 --version | grep -P -o 'Ver\s+[\w\.-]+'| awk '{print $2}'` + +#extract the md5 digest + +MYMD5=`md5sum -b $1 | awk -v Field=1 '{print $1}'` + +MYVER="$FULL_MYVER" +echo $FULL_MYVER | grep 'log' > /dev/null + + +if [ $? = 0 ]; then + MYVER=`echo "$MYVER" | grep -P -o '.+(?=-log)'` +fi + +echo "set logging on" > offsets.gdb +echo 'printf "{\"'$MYVER'\",\"'$MYMD5'\", %d, %d, %d, %d, %d, %d}", ((size_t)&((THD *)log_slow_statement)->query_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->thread_id) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->main_security_ctx) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->command) - (size_t)log_slow_statement, ((size_t)&((THD *)log_slow_statement)->lex) - (size_t)log_slow_statement, (size_t)&((LEX*)log_slow_statement)->comment - (size_t) log_slow_statement' >> offsets.gdb + +SYMPARAM="" +if [ -n "$2" ]; then + SYMPARAM="-s $2 -e" +fi + +gdb -n -q -batch -x offsets.gdb $SYMPARAM $1 > /dev/null 2>&1 + +if [ $? != 0 ]; then + echo "GDB failed!!!" > /dev/stderr + exit 2 +fi + +OFFSETS=`cat gdb.txt` +echo "//offsets for: $1 ($FULL_MYVER)" +echo "$OFFSETS," + +#clean up +rm gdb.txt +rm offsets.gdb + diff --git a/src/hot_patch.cc b/src/hot_patch.cc index 6b5ac93..9662c25 100644 --- a/src/hot_patch.cc +++ b/src/hot_patch.cc @@ -12,11 +12,6 @@ - -#define unprotect(addr,len) (mprotect(addr,len,PROT_READ|PROT_WRITE|PROT_EXEC)) -#define protect(addr,len) (mprotect(addr,len,PROT_READ|PROT_EXEC)) -#define GETPAGESIZE() sysconf (_SC_PAGE_SIZE) - #define unprotect(addr,len) (mprotect(addr,len,PROT_READ|PROT_WRITE|PROT_EXEC)) #define protect(addr,len) (mprotect(addr,len,PROT_READ|PROT_EXEC)) #define GETPAGESIZE() sysconf (_SC_PAGE_SIZE) @@ -68,15 +63,6 @@ static void WriteJump(void *pAddress, ULONG_PTR JumpTo) *pCur++ = 0xE9; // jmp +imm32 *((ULONG_PTR *)pCur) = JumpTo - (ULONG_PTR)pbJmpSrc; -/* old jump indirect requires 10 bytes (TOO big) - *pCur = 0xff; // jmp [addr] - *(++pCur) = 0x25; - pCur++; - *((DWORD *) pCur) = (DWORD)(((ULONG_PTR) pCur) + sizeof (DWORD)); - pCur += sizeof (DWORD); - *((ULONG_PTR *)pCur) = JumpTo; -*/ - #else *pCur = 0xff; // jmp [rip+addr] @@ -182,54 +168,7 @@ int hot_patch_function (void* targetFunction, void* newFunction, void * trampoli else { return -1; - } - /* OLD unused code - int res = unprotect((void *)trampolinePage,PAGE_SIZE); - if(res != 0) - { - sql_print_error("%s error un protecting trampoline page: 0x%x errno: %s. Aborting.",log_prefix, trampolinePage, strerror(errno)); - return -1; - } - //copy original code we are going to write over - memcpy( trampolineFunction, targetFunction, TRAMPOLINE_COPY_LENGTH) ; - //copy the jmp back to original code - memset( (void *)((DATATYPE_ADDRESS)trampolineFunction + TRAMPOLINE_COPY_LENGTH), JMP_OPCODE, OPCODE_LENGTH ) ; - //calculate where we want to jump back. The jump is relative. - //We are jumping from: trampolineFunction + TRAMPOLINE_COPY_LENGTH + MIN_REQUIRED_FOR_DETOUR - //to: targetFunction + TRAMPOLINE_COPY_LENGTH - //the diff is: targetFunction + TRAMPOLINE_COPY_LENGTH - (trampolineFunction + TRAMPOLINE_COPY_LENGTH + MIN_REQUIRED_FOR_DETOUR) - //TRAMPOLINE_COPY_LENGTH can be removed from both sides to get: - DATATYPE_ADDRESS jumpBackAddress = (DATATYPE_ADDRESS)targetFunction - ((DATATYPE_ADDRESS)trampolineFunction + MIN_REQUIRED_FOR_DETOUR); - //copy the location to the trampolineFunction - memcpy( (void *)((DATATYPE_ADDRESS) trampolineFunction + TRAMPOLINE_COPY_LENGTH + OPCODE_LENGTH), &jumpBackAddress, ADDRESS_LENGTH) ; - //protect the page - protect((void *)trampolinePage,PAGE_SIZE); - - //now modify the code of the target function - DATATYPE_ADDRESS targetPage = get_page_address(targetFunction); - cond_info_print(info_print, "%s targetPage: 0x%x targetFunction: 0x%x",log_prefix, targetPage, targetFunction); - - res = unprotect((void *)targetPage,PAGE_SIZE); - if(res == 0) - { - cond_info_print(info_print, "%s unprotect res: %d",log_prefix, res); - cond_info_print(info_print, "%s setting jump code: 0x%x length: %d at: 0x%x", log_prefix, JMP_OPCODE, OPCODE_LENGTH, targetFunction); - memset(targetFunction, JMP_OPCODE, OPCODE_LENGTH) ; - //calculate where we want to jump to. Jump is relative (see above jump calcluation) - DATATYPE_ADDRESS jumpAddress = (DATATYPE_ADDRESS)newFunction - ((DATATYPE_ADDRESS)targetFunction + MIN_REQUIRED_FOR_DETOUR); - DATATYPE_ADDRESS targetFuncJumpAddress = (DATATYPE_ADDRESS)targetFunction + OPCODE_LENGTH; - cond_info_print(info_print, "%s setting jump address: 0x%x length: %d at: 0x%x", log_prefix, jumpAddress, ADDRESS_LENGTH, targetFuncJumpAddress); - memcpy((void *)targetFuncJumpAddress, &jumpAddress, ADDRESS_LENGTH) ; - res = protect((void *)targetPage,PAGE_SIZE); - cond_info_print(info_print, "%s protect res: %d",log_prefix, res); - } - else - { - sql_print_error("%s error un protecting target function page: 0x%x errno: %s. Aborted.", log_prefix, targetPage, strerror(errno)); - return -2; - } - return 0; - */ + } } @@ -248,21 +187,5 @@ void remove_hot_patch_function (void* targetFunction, void * trampolineFunction, cond_info_print(info_print, "%s targetPage: 0x%x targetFunction: 0x%x",log_prefix, targetPage, targetFunction); UnhookFunction ((ULONG_PTR) targetFunction, (ULONG_PTR)trampolineFunction,trampolinesize); - return; - - /** OLD unused code - int res = unprotect((void *)targetPage,PAGE_SIZE); - if(res == 0) - { - cond_info_print(info_print, "%s unprotect res: %d", log_prefix, res); - cond_info_print(info_print, "%s copying org code from trampoline function: 0x%x length: %d to: 0x%x", log_prefix, trampolineFunction, TRAMPOLINE_COPY_LENGTH, targetFunction); - memcpy(targetFunction, trampolineFunction, TRAMPOLINE_COPY_LENGTH) ; - res = protect((void *)targetPage,PAGE_SIZE); - cond_info_print(info_print, "%s protect res: %d",log_prefix, res); - } - else - { - cond_info_print(info_print, "%s ERROR un protecting page: 0x%x errno: %d", log_prefix, targetPage, errno); - } - */ + return; }