void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));
吸引我的地方就是 callback function,用以作比較資料之用。探討與 shellcode 的關聯前,先來寫個簡單的範例程式:(qsort.c)#include <stdlib.h> #include <stdio.h> static int cmp_func(int* a, int* b) { return (*a - *b); } int array[10] = { 5, 9, 2, 8, 1, 4, 7, 10, 3, 6 }; int main() { int i; qsort(array, 10, sizeof(array[0]), cmp_func); for (i = 0; i < 10; i++) { printf("-> %d\n", array[i]); } return 0; }這個程式碼的輸出很容易想像,就是將 1, 2, 3, ..., 10 排序印列,那我們作點觀察:
$ gcc -Os -o qsort qsort.c 2>/dev/null $ objdump -xd qsort | grep -A8 "<cmp_func>" 08048384cmp_func 函式的 IA32 機械碼前半段是處理 C-style stack,實做部份則是以下兩行組合語言程式碼:: 8048384: 55 push %ebp 8048385: 89 e5 mov %esp,%ebp 8048387: 8b 45 08 mov 0x8(%ebp),%eax 804838a: 8b 55 0c mov 0xc(%ebp),%edx 804838d: 5d pop %ebp 804838e: 8b 00 mov (%eax),%eax 8048390: 2b 02 sub (%edx),%eax 8048392: c3 ret
804838e: 8b 00 mov (%eax),%eax 8048390: 2b 02 sub (%edx),%eax於是我們取上述的機械碼當作 shellcode,改寫之前的範例程式:(qsort-shellcode.c)
#include <stdlib.h> #include <stdio.h> int array[10] = { 5, 9, 2, 8, 1, 4, 7, 10, 3, 6 }; int main() { int i; char *shellcode = "\x8b\x00\x2b\x02\xc3"; qsort(array, 10, sizeof(array[0]), shellcode); for (i = 0; i < 10; i++) { printf("-> %d\n", array[i]); } return 0; }注意,shellcode 的實做需要補上 ret,否則 qsort 就玩不下去了。
很有趣.
但要注意 EAX, EDX 沒正確初始化的情形.
it doesn't work on my machine
IMO, it should include all the codes, "\x55...\xc3", with your codes, i got
segment fault, i wonder maybe because of
different compilers?
To Joshua,
I have tested with gcc-4.1 and gcc-3.4 under Ubuntu Linux/IA32. The proper way to use the shellcode is handling stack frame in the correct approach instead of the reduced method I took in the above.
So, it is really interesting that we could write such less portable C-code with customized qsort callback function if we think of being requested.
由 jserv 發表於 May 15, 2007 12:40 AM: D
由 Joshua 發表於 May 17, 2007 02:32 AMFIXED.
char *shellcode = ""YXZ\x83\xec\f\213\0+\x2\303";
qsort(array, 10, sizeof(array[0]), shellcode);