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 unprotect(addr,len) (mprotect(addr,len,PROT_READ|PROT_WRITE|PROT_EXEC))
|
||||||
#define protect(addr,len) (mprotect(addr,len,PROT_READ|PROT_EXEC))
|
#define protect(addr,len) (mprotect(addr,len,PROT_READ|PROT_EXEC))
|
||||||
#define GETPAGESIZE() sysconf (_SC_PAGE_SIZE)
|
#define GETPAGESIZE() sysconf (_SC_PAGE_SIZE)
|
||||||
|
@ -68,15 +63,6 @@ static void WriteJump(void *pAddress, ULONG_PTR JumpTo)
|
||||||
*pCur++ = 0xE9; // jmp +imm32
|
*pCur++ = 0xE9; // jmp +imm32
|
||||||
*((ULONG_PTR *)pCur) = JumpTo - (ULONG_PTR)pbJmpSrc;
|
*((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
|
#else
|
||||||
|
|
||||||
*pCur = 0xff; // jmp [rip+addr]
|
*pCur = 0xff; // jmp [rip+addr]
|
||||||
|
@ -183,53 +169,6 @@ int hot_patch_function (void* targetFunction, void* newFunction, void * trampoli
|
||||||
{
|
{
|
||||||
return -1;
|
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);
|
UnhookFunction ((ULONG_PTR) targetFunction, (ULONG_PTR)trampolineFunction,trampolinesize);
|
||||||
return;
|
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