added offset-extract. hot_patch cleanup.

pull/8/merge
Guy Lichtman 2012-04-11 15:56:24 +03:00
parent 6db2a9f158
commit 2109a1030d
2 changed files with 49 additions and 79 deletions

View File

@ -0,0 +1,47 @@
#!/bin/sh
if [ $# = 0 ]; then
echo "Usage: $0 <mysqld executable> [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

View File

@ -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;
}