added offset-extract. hot_patch cleanup.
parent
6db2a9f158
commit
2109a1030d
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
@ -183,53 +169,6 @@ int hot_patch_function (void* targetFunction, void* newFunction, void * trampoli
|
|||
{
|
||||
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;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,20 +188,4 @@ void remove_hot_patch_function (void* targetFunction, void * trampolineFunction,
|
|||
|
||||
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);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue