banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành Windows giúp mình tìm lỗi mấy chương trình C này với  XML
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 28/02/2009 14:42:56 (+0700) | #31 | 171394
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
@OSato: ý là bạn nói đi tìm lỗi của những bài này là vô ích, bởi trong thực tế, nó phức tạp hơn nhiều?

Ờ thì tại mình nghĩ mình dốt, nên ráng tập làm mấy cái đơn giản này trước. Gặp cái nào khó quá, không làm được thì mình đành tìm trên Google xem bọn nó giải thế nào, rồi gửi lên đây lấy le vậy. Gì chứ mình xài Google tốt lắm.

À mà nói nhiều làm chi, chắc bạn OSATO toàn chơi cỡ mấy bài trên Phrack, nên mình dại mồm dại miệng nhờ bạn giải giùm mình bài số 7. Ông thầy cho về nhà từ học kỳ trước mà tới giờ mình vẫn chưa giải được. Ối bạn đừng chê nó đơn giản quá nên không thèm làm nha, mình tủi thân lắm huhuhu.

@rest: Nhân dịp...hết tháng 2, mình tặng tất cả các bạn một câu thế này của Mark Twain:

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.
 


[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 28/02/2009 15:09:47 (+0700) | #32 | 171397
0SAT0
Member

[Minus]    0    [Plus]
Joined: 18/06/2008 19:17:58
Messages: 18
Offline
[Profile] [PM]
Hic, sorry smilie mình hok hề có ý đó , mình có giải ra đâu , chỉ có điều mình đã nói kĩ đó là ý kiến cá nhân mình .
Chả dám chê ai hay coi thường ai cả , chắc lời lẽ hơi quá đáng , một lần nữa xin lỗi bạn . Mình sẽ xóa bài để ko làm hỏng topic của bạn .
À chắc bạn học ở trường ngoài nước rồi , mình chỉ học ở một trường ở Việt Nam , hok dạy security nên chắc trình độ còn thua xa bạn lắm , mình thường coi ké giáo trình ở các trường khác và thèm muốn smilie .
Cuối cùng : mình hok giỏi english cho lắm , cái câu bạn nói mình hiểu sơ sơ , hình như bạn đang nói mình thì phải smilie
Thôi xóa bài .
À quên , mình có coi vài bài của bạn , mình hok thích cách nói chuyện của bạn lắm , bạn giỏi nhưng cũng đừng coi thường người khác quá , mà trong topic này cũng thế , bài trả lời mình vừa rồi ,bạn than vãn nhưng là đang chửi bới mình chứ gì smilie Thôi tùy , ăn nói sâu xa quá mệt óc lắm . Mà bài số 7 bạn nhờ mình giải đâu nhỉ ? mình có thấy đâu smilie Cái kiểu cứ nâng người ta lên để đạp người ta xuống nghe thì nó ngọt ngào dễ chịu lắm nhưng mà mình thấy nó chát ngắt thế nào ây gì mà ừ thì mình dốt rồi mình google lấy lệ smilie ...... , thấy nó abczyx lắm lận smilie
Mình hok làm những bài này hok phải vì nghĩ đơn giản mà theo mình hack = change + creative . Còn những cái bài thế này là một cách rập khuôn , thế này đi , mình có một nhóm , tất cả cùng ngồi lại lọc ra các function có nguy cơ cao (theo cái development guide trên kia) rồi ở mỗi function xem nó có bao nhiêu cách khai thác , và tiếp tục bàn bạc xem khai thác ở điểm nào thì được smilie theo bạn thì một nhóm hơn chục con ngừoi , có thể tìm ra lỗi ở function nào và làm sao attack nó ko ? Nếu không dc thì mình sẽ thử cùng nhóm giải quyết các bài này . Còn nếu bạn nghĩ là dc thì ......
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 28/02/2009 18:02:44 (+0700) | #33 | 171401
StarGhost
Elite Member

[Minus]    0    [Plus]
Joined: 29/03/2005 20:34:22
Messages: 662
Location: The Queen
Offline
[Profile] [PM]

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. smilie

Đù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.
Mind your thought.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 28/02/2009 22:37:10 (+0700) | #34 | 171409
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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 smilie

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 smilie
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 06:06:19 (+0700) | #35 | 171565
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 06:34:37 (+0700) | #36 | 171566
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
Các bạn có thể download C99 ở đây: http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 07:09:44 (+0700) | #37 | 171568
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
Để 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;    
}


[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 13:43:14 (+0700) | #38 | 171602
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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 smilie
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 14:50:28 (+0700) | #39 | 171609
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
@nbthanh: mình nghĩ bạn nên đọc C99 đi, tự vì trong đó nó nói hết tại sao bạn lại quan sát được như thế. Và rất tiếc là C99 nó nói khác với cách hiểu của bạn.

Thật tế với ví dụ của bạn, không cần phải compile rồi chạy, mình cũng có thể tính được giá trị của hai biến i và c, thông qua các luật chuyển đổi trong C99.

Như mình đã nói ở một bài ở trên, MAX_LEN, sau bước preprocessing, trở thành 256, và sẽ được xem như là một integer constant. Để tính kiểu cho một integer constant, thì C99 (các chuẩn trước đó thì hình như chưa có luật n), sẽ tìm chọn từ trên xuống dưới, bắt đầu bằng int (rồi long int, rồi long long int...), xem kiểu nào có thể lưu giá trị của integer constant đó. Ở trường hợp này, do MAX_LEN là 256, nên kiểu được chọn là int. Sở dĩ C99 không chọn kiểu nhỏ hơn, ví dụ như char hay short, bởi vì các kiểu này, sau đó cũng sẽ bị đổi sang int, do phép biến đổi integer promotion.

Biểu thức 256 - 10 là một biểu thức số học nhị phân, nên việc tính kiểu cho nó sẽ tuân theo nhóm luật gọi là usual arithmetic conversion. Ở đây mình có hai cái operand cùng kiểu int, nên không cần phải chuyển đổi gì thêm nữa, biểu thức này sẽ có kiểu là int. Trong C99 cũng có nói, int là signed hay unsigned là implementation-defined, và thông thường thì nó sẽ là signed.

Rồi bây giờ nói đến hai trường hợp cụ thể mà bạn nbthanh quan sát được. Trong trường hợp i = MAX_LEN - 10, do i được khai báo là int, cùng kiểu với MAX_LEN - 10, nên giá trị của MAX_LEN - 10 sẽ được gán cho i mà không cần phải chuyển đổi gì nữa. Trong trường hợp c = MAX_LEN - 10, do c là char, nên khi gán thế này, một phép biến đổi từ int sang char (mà C99 gọi là simple conversion) sẽ diễn ra: số int sẽ bị truncated, chỉ lấy 8 bit cuối của số int này, và gán cho số char.

Xét 8 bit cuối của số 246 = MAX_LEN - 10: 1111 0110. 8 bit này là dạng biểu diễn lưu trên máy tính của c. Tương tự, như trường hợp int, char là signed hay unsigned là implementation-defined, và thông thường là signed. Nghĩa là muốn tính xem 1111 0110 là biểu diễn của con số bao nhiêu, ta phải lấy bù hai của nó.

Bù một: 0000 1001
Bù hai: 0000 1010 = 10

Như vậy 1111 0110 là biểu diễn của giá trị là -10. Điều này giải thích tại sao bạn nbthanh thấy giá trị này. 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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 15:06:06 (+0700) | #40 | 171610
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
Mình nghĩ những tranh luận ở đây thể hiện rất rõ lý do tại sao mình gửi mấy bài này lên đây: ngay cả người đã làm C/C++ nhiều năm vẫn có thể không hiểu rõ cách mà C/C++ xử lý các con số. Mà không chỉ trong C/C++, vấn đề này cũng lập lại ở các ngôn ngữ như Java hay C#. Nên mình có lời khuyên là bạn nào viết code để sống thì nên tìm hiểu kỹ những câu hỏi này, xem mình có thật sự hiểu rõ chuyện gì xảy ra hay không.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 02/03/2009 16:25:46 (+0700) | #41 | 171612
[Avatar]
Z0rr0
Q+WRtaW5pc3RyYXRvc+g

Joined: 14/08/2002 12:52:01
Messages: 1323
Location: Underground
Offline
[Profile] [PM] [WWW] [Yahoo!]
Đồng tình với choc_ vụ làm nhiều năm với C/C++ mà vẫn khó rõ ngọn ngành nếu không đào sâu gốc rễ. Đọc những tranh luận trên đây quả là thú vị và đáng học hỏi smilie

Vụ if (i < (MAX_LEN - 1)) ... theo tui hiểu thì đơn giản, vì i được khai báo unsigned int (range từ 0 - 4,294,967,295), MAX_LEN - 1 bằng -1 hay 0xffffffff, khi so sánh nó type cast cả 2 phía về unsigned thì đương nhiên vế phải sẽ lớn hơn.

BTW. Đọc tiêu đề thấy "chương trình C" sao nhiều tranh luận vẫn lôi "C++" ra nhỉ.
Hibernating
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 01:07:45 (+0700) | #42 | 171645
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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).
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 02:00:58 (+0700) | #43 | 171651
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 02:02:10 (+0700) | #44 | 171652
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
@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 đó.

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.

Mình chưa làm thử, nhưng mình đồ là thay vì gán trực tiếp MAX_LEN - 1 cho c, bạn thử ép kiểu từ i qua c, thì bạn sẽ thấy đoạn mã mà bạn đang tìm, bởi lúc này vế phải không còn là một integer constant expression nữa rồi.

Mà thôi, mình làm luôn cho bạn coi nè (compiled bằng gcc-4.x trên linux-x86):

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 03:22:31 (+0700) | #45 | 171661
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 03:36:48 (+0700) | #46 | 171664
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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)?
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 03/03/2009 03:40:44 (+0700) | #47 | 171665
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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 smilie 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? smilie
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 00:25:16 (+0700) | #48 | 171757
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
@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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 01:31:26 (+0700) | #49 | 171769
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 01:42:49 (+0700) | #50 | 171772
StarGhost
Elite Member

[Minus]    0    [Plus]
Joined: 29/03/2005 20:34:22
Messages: 662
Location: The Queen
Offline
[Profile] [PM]
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.
Mind your thought.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 01:50:06 (+0700) | #51 | 171776
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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 đó.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 02:58:31 (+0700) | #52 | 171792
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
@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à, mấy cái preprocessing number sẽ chỉ có hai kiểu: hoặc là float hoặc là integer, nó đâu có ghi là sẽ phụ thuộc vào ngữ cảnh đâu bạn :-p. Việc convert một token sang loại token nào chỉ phụ thuộc vào cái literal string của token đó thôi, không hề phụ thuộc vào ngữ cảnh. Đây là kiến thức cơ bản của môn compiler mà phải không? Rồi từ loại token, người ta mới suy ra kiểu của token đó. Cái này mình đã nói ở trên rồi, kiểu của MAX_LEN sẽ là int.

Nếu MAX_LEN là int, thì biểu thức MAX_LEN - 1 sẽ có kết quả thuộc kiểu int (như mình đã chứng minh bằng sizeof). Đây cũng là điểm mà mình muốn nói đến từ đầu. Thậm chí sizeof(MAX_LEN - 1) cũng bị dịch một phát thành movel 0x4, $eax, nghĩa là compiler nó tính ra giá trị cụ thể (mình nghĩ là nó làm ở bước translation 7), rồi ghi luôn vào register, chứ không hề sinh mã trung gian.

Nếu không lầm thì mình đã đưa ra một ví dụ có mã trung gian cho bạn rồi. Chắc là bạn bỏ sót, giờ mình đưa ra một ví dụ mà mình vừa mới nghĩ ra:

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 04/03/2009 13:11:54 (+0700) | #53 | 171849
nbthanh
HVA Friend

Joined: 21/12/2001 14:51:51
Messages: 429
Offline
[Profile] [PM]

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 smilie

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).
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 11/03/2009 06:47:21 (+0700) | #54 | 172772
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
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
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 11/03/2009 06:53:43 (+0700) | #55 | 172773
[Avatar]
secmask
Elite Member

[Minus]    0    [Plus]
Joined: 29/10/2004 13:52:24
Messages: 553
Location: graveyard
Offline
[Profile] [PM] [WWW]

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 . smilie
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 11/03/2009 07:10:44 (+0700) | #56 | 172775
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
http://www.mediafire.com/download.php?zymq4nzn2yl
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 14/03/2009 12:09:36 (+0700) | #57 | 173174
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
Mình mới tìm được một số tài liệu khá hay trên mạng về đề tài này, các bạn tham khảo nha:

1. Chương 6 - C language issues của The Art of Software Security Assessment (được xem là sách gối đầu giường của những ai muốn nghiên cứu việc tìm lỗi trong phần mềm, một trong rất ít cuốn sách làm thay đổi cả ngành an toàn thông tin): http://www.awprofessional.com/content/images/0321444426/samplechapter/Dowd_ch06.pdf.

Chương 6 này viết rất chi tiết về các vấn đề thường gặp khi lập trình bằng ngôn ngữ C.

2. Chương 5 của cuốn "Secure Coding in C and C++", tác giả là Robert Seacord, chuyên gia về viết mã an toàn của CERT: http://www.awprofessional.com/content/images/0321335724/samplechapter/seacord_ch05.pdf

Chương 5 này viết rất chi tiết về các vấn đề liên quan đến số nguyên. Khác với cuốn ở trên, Seacord còn đưa ra một số biện pháp để viết mã an toàn hơn.

3. Tham khảo thêm tài liệu https://www.securecoding.cert.org/confluence/display/seccode/CERT+C+Programming+Language+Secure+Coding+Standard. Trong đây họ liệt kê tất cả các dạng lỗi thường gặp khi viết bằng C, và cách sửa chương trình để không bị lỗi nữa.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 14/03/2009 13:39:36 (+0700) | #58 | 173180
[Avatar]
Z0rr0
Q+WRtaW5pc3RyYXRvc+g

Joined: 14/08/2002 12:52:01
Messages: 1323
Location: Underground
Offline
[Profile] [PM] [WWW] [Yahoo!]
Hay lắm, cảm ơn choc_
Hibernating
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 31/03/2009 13:51:50 (+0700) | #59 | 175459
choc_
Member

[Minus]    0    [Plus]
Joined: 27/01/2009 06:46:01
Messages: 122
Offline
[Profile] [PM]
mắc cười quá, hôm nay mới xem được một cái tin thế này:

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.
[Up] [Print Copy]
  [Question]   Re: giúp mình tìm lỗi mấy chương trình C này với 27/05/2009 04:11:03 (+0700) | #60 | 181992
the_mistake
Member

[Minus]    0    [Plus]
Joined: 21/09/2008 12:33:09
Messages: 31
Offline
[Profile] [PM]
Đọc xong chủ đề này em cảm thấy rất hay mặc dù với kiến thức hiện tại em chẳng hiểu được gì, em rất muốn tìm hiểu để nắm rõ hơn,sâu hơn về ngôn ngữ mà em đang học đó là C++

Vì vậy em có 1 vài câu hỏi ( xin lỗi vì em hỏi tại đây, nơi các anh bàn về C , nhưng em nghĩ tương tự) , đó là:

- Có phải các anh đang bàn luận về ' diassembly' không ạ, em thấy khi biên dịch 1 chương trình C++ nào đó, trình biên dịch không hiển thị lỗi ( em thường hay gặp ở các bài cấp phát động, hay con trỏ, tham chiếu) , vẫn chạy nhưng báo lỗi bộ nhớ ( hay thường là thông báo close chương trình (incorrect, invalid)) hoặc nếu trong máy tồn tại một trình debug nào đó thì nó hỏi mình có debug hay không, khi em chọn debug( máy có Visual Studio 2008) thì sẽ hiện ra 1 bảng thông báo thế này:

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ì?
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|