ข่าวเกมส์

1/10/2552

Basic Crack

วีดีโอสอนการแก้ Basiccrack.exe เอาไว้เรียนการ RE ในเบื้องต้น ตามที่สอนใน พื้นฐาน RE




สำหรับบทความนี้หวังไว้ว่าน่าจะเป็นการโปรโหมตให้หลายท่านมา ศึกษา เรื่อง แคร้ก กันบ้าง

Crack คืออะไร ?

กล่าวโดยภาพรวม แคร้ก คือการ แก้ไขการทำงานของโปรแกรมให้ทำตามจุดประสงค์ของผู้แคร้ก

Crack ทำไม ?

ท่านผู้อ่านก็คงจะเคยผ่านการใช้งานซอฟแวร์ แอพลิเคชั่น โปรแกรม ต่างๆมาไม่น้อย และน่าจะได้ยินและคุ้นกับคำว่า Shareware Freeware Demo ....shareware ส่วนใหญ่เป็นโปรแกรมทดลองใช้มักมีการกำหนดเวลาให้เราใช้ กำหนดว่าเราสามารถใช้งานส่วนไหนของโปรแกรมได้บ้างในขณะที่เป็น Shareware ,FreeWare เป็นโปรแกรมที่แจกฟรีเพื่อสนองความต้องการของผู้ใช้ ส่วนใหญ่มักจะเป็นในรูปของโปรแกรมขนาดเล็กๆ เราสามารถใช้ได้เต็มที่ , Demo เป็นซอฟแวร์ที่มีการตัดเอาบางการทำงานของโปรแกรมออก ให้ผู้ใช้ใช้งานได้ไม่จำกัดเวลา แต่ว่า คุณจะใช้บริการการทำงานอื่นๆที่เขาตัดออกไม่ได้อย่างสิ้นเชิง ซึ่งถ้าหากผู้ใช้ต้องการใช้งานโปรแกรมได้เต็มที่ จะต้องเสียสิ่งของที่มีมูลค่าไปแลกกับ รหัสมาลงทะเบียนเพื่อใช้งานโปรแกรมได้เต็มที่ แต่ถ้าหากว่าคุณไม่มีสิ่งของมีค่าล่ะ แต่ถ้าคุณอยากใช้ คุณจะทำยังไง? แคร้กนั่นเอง

Crack มีโอกาสสำเร็จมากน้อยเพียงใด?

เบื้องต้นเราทราบว่า โปรแกรมชนิด Shareware มักมีการจำกัดด้าน เวลา ด้านการใช้งาน แต่เมื่อลงทะเบียนเสร็จโปรแกรมก็จะใช้งานได้ตามปกติ กลไก ทั้งหลายเปลี่ยนแปลงได้เพราะรหัสๆเดียวนั้นๆ ถ้าหากเราได้รหัสนั้นๆมาก็จะสามารถใช้โปรแกรมเต็มรูปแบบได้เช่นเดียวกันโดยไม่ต้องอัพเดทโปรแกรมใหม่ กล่าวโดยรวมคือ Shareware เป็นโปรแกรมเต็มรูปแบบ(Full) แต่ต้องการรหัสไปปลดล็อคแค่นั้นเอง การเปรียบเทียบรหัสมันอยู่ที่เครื่องเราทำอะไรก็อยู่ที่เครื่องเรา ดังนั้น มีโอกาสเกือบร้อยเปอร์เซ็นที่จะแคร้กโปรแกรม ชนิด Shareware ได้

Crack แตกต่างกับ Hack อย่างไร?

ส่วนมากเรามักจะคุ้นเคยกับคำว่า hack ขอให้ความหมายเกี่ยวกับการ การทำงานในเรื่องระบบเน็ตเวิร์ค ส่วนมากจะใช้ภาษาระดับสูงแต่ แคร้ก จะใช้ภาษาระดับต่ำในการศึกษา ,Hack คนอื่นมีโอกาสรู้ แต่ Crack คุณทำคุณรู้คนเดียวhack ส่วนมากใช้ได้จากบั้ก(Bug) Crack ส่วนมากทำได้เนื่องจากความไม่รอบคอบของผู้เขียนโปรแกรม hack ได้คุณได้คุมระบบ crack ได้คุณคุมโปรแกรมนั้น

Crack ได้อย่างไร?

พื้นฐานเบื้องต้นเรามารู้จักกันก่อนว่า คอมพิวเตอร์ใช้ภาษาอะไร? huhhuhhuh??
ภาษาคอมพิวเตอร์แบ่งออกเป็น 3 ระดับ
1.ภาษาเครื่อง ภาษาเครื่องคือภาษาที่ คอมพิวเตอร์เข้าใจ ภาษาเครื่องมีสองพยัญชนะคือ 0 และ 1 (ภาษาไทยเรามี 44 พยัญชนะ) 0 และ 1 ให้ความหมายได้อย่างไร เลข 0 และ 1 สามารถแทนอักษรได้ เช่น หากเรานับโดยตรง จำนวน 3 จะได้ 100 มีตารางง่ายๆดังนี้

01
10
11
100
101
110
111

เลข 1 จะเพิ่มมาจาก บิตข้างขวาเรื่อยๆจน ได้ 1 เต็มทุกตัว ก็จะเพิ่มจำนวนบิต(หลัก)ขึ้นมา เช่น 111 เพิ่มอีก จะเป็น 1000 เป็นการนับเลขอย่างง่าย ภาษาเครื่องหรือเลขฐานสอง 8บิต(1 ไบต์) = ตัวอักษรตัวหนึ่ง เช่น
ตัวอักษร "a" = 0110 0001 ของเลขฐานสอง ซึ่งก็เป็นเรื่องยากพอสมควรที่มนุษย์จะเข้าใจตัวเลขหลายๆตัวกว่าจะเป็นคำๆหนึ่ง

2.ภาษาระดับต่ำ เช่น เลขฐาน 8 เลขฐาน 16(hexadecimal) Assembly ascii เลขฐานสิบ จะอธิบายเฉพาะที่สำคัญในการแคร้กนะ

- เลขฐาน16 (hex) ประกอบไปด้วย 0123456789ABCDEF ครบ 16ตัวใช้ย่อเลขฐานสองเพื่อลดขนาดลง เลขฐาน16 ขนาด2ตัวจะ เท่ากับ 1ไบต์(8 บิต) เช่น ฐานสองของ a = 0110 0001 ฐาน16ของ a = 61 ส่วนมากเมื่อมีการแก้ไขโค้ดของโปรแกรมมักจะแก้ไขด้วยฐาน16

- Assembly เป็นภาษาที่ใช้ตัวอักษรของภาษาอังกฤษมาแทนตัวเลข เพื่อให้เกิดความเข้าใจมากขึ้นเวลาเราอ่านโค้ดเช่น hex 74 เป็น assembly จะแทนด้วยคำสั่ง JE โดยส่วนมากเวลาแคร้กเราจะต้องใช้ภาษานี้เป็นหลักและเวลาแก้ต้องใช้ เลขฐาน16 ปัจจุบันมีโปรแกรมชนิด Assembler ซึ่งเป็นโปรแกรมอ่านภาษา asm ของ โปรแกรมที่เราจะแคร้ก

- Ascii (American standard code for information interchange ไม่รู้ถูกเปล่าเเขียนเท่าที่จำ) เป็นการใช้ตัวเลขแทนด้วยตัวอักษรต่างๆเช่น ascii a(ฐานสิบ) = 97 ,hex a = 61 Binary(ฐานสอง) = 0110 0001 สำหรับการใช้ภาษาascii เบื้องต้น ลองกด Alt ค้างแล้วกด เลข97 สิครับ ก็จะได้ตัว a มา asciiสามารถแทนได้ ตัวอักษรได้แค่ 256 ตัวอักษรเท่านั้น แต่ถ้า Unicode จะแทนได้ 65536อักษร

- เลขฐานสิบ คือ เลขที่เราใช้กันในปัจจุบัน 0 1 2 3 4 5 6 7 8 9

3.ภาษาระดับสูง เช่น โปรแกรมเขียนโปรแกรม = vc vb c++ fortan delphi ฯลฯ เวลาเราเขียนโปรแกรมเสร็จเมื่อจะสร้างไฟล์ exe ของโปรแกรมขึ้นมาจะผ่านกระบวนการที่เรียกว่า Compile ซึ่งเป็นกระบวนการแปลโค้ดทั้งหมดที่เราเขียนเป็นภาษาเครื่องซะก่อนจึงจะทำงานได้ เช่น หลายท่านคงเคยเปิดไฟล์ นามสกุล exe ด้วย notepad และทำการแก้ไขตัวอักษร แต่เมื่อ save มันก็มักจะใช้ง่ายไม่ได้ เนื่องจากมันไม่ได้ผ่านกระบวนการแปลงให้เป็นภาษาเครื่องนั่นเอง ที่มีภาษาระดับสูงก็เพราะ ทำให้เราเกิดความเข้าใจในโค้ดที่เราเขียนมากขึ้นเวลาเราอ่านโค้ดก็สามารถเข้าใจได้เลย

Crack โดยใช้อะไร ?

เครื่องมือที่เราใช้ในการแคร้กคือ Debugger เป็นโปรแกรมจำพวกแปลง ภาษาให้อยู่ในระดับภาษาระดับต่ำเช่น asm โดยโปรแกรมจะถูก Load เข้ามาและสั่งรัน เราเสมือนควบคุมโปรแกรมนั้นด้วย Debugger สามารถ Pause เพื่อหยุดการทำงาน ของโปรแกรม สามารถ Step over เพื่อรันโค้ดไปทีละบรรทัด ( ถ้าเป็นหนังสือ จะเท่ากับเราอ่านแค่หัวข้อ) Step Into เพื่อรันโค้ดไปทีละบรรทัดแต่ต่างกันที่ว่ามักจะรันไปทุกวอกทุกมุมของโค้ด(อ่านเยอะขึ้นเรื่อยๆ)

บทความนี้หวังว่าจะเป็นประโยชน์เบื้องต้นที่ใช้สำหรับการแคร้ก บทความต่อไปจะนำเสนอ การแคร้ก โปรแกรมโดยมีตัวอย่างโปรแกรมเขียนเองมาเพื่ออธิบายให้เข้าใจมากขึ้นก่อนที่จะไปถึงขั้นแคร้กโปรแกรมจริงๆ


บทความที่ 2

How To Crack ? จะแคร้กได้อย่างไร?

จากบทความที่แล้ว บทความนี้จะนำเสนอ ให้ผู้อ่านมองทะลุเกี่ยวกับการแคร้ก



โปรแกรมนี้สร้างจาก โปรแกรม Delphi ซึ่งเขียนด้วยภาษาระดับสูง ภายในโค้ด ใช้คำสั่งว่า

If edit1.text = '01234567' then
showmessage('Correct')
else
showmessage('Incorrect')

เป็นโค้ดง่ายๆที่มีการตรวจสอบภายในช่อง edit นั้นว่า ข้อความในช่องนั้น คือ 01234567 หรือไม่ ถ้าใช่ก็ แสดงกล่องข้อความว่า Correct แต่ถ้าเป็นอย่างอื่น ( Else ) ให้แสดงกล่องข้อความว่า Incorrect เขียนเป็น flow chart แสดงขั้นตอนการทำงานของโปรแกรมให้ผู้อ่านเข้าใจได้มากขึ้นดังรูปข้างล่าง



จะใช้โปรแกรมนี้จำลองให้ผู้อ่านมองมันเสมือนกันกับการ ลงทะเบียน โปรแกรมอื่นเพื่อให้ กลายเป็น Registered ทำให้เราสามารถใช้งานได้อย่างสมบูรณ์ โปรแกรมทั้งหลาย ย่อมมีทางไป แสดงข้อความว่าถูก และผิด เมื่อเกิดการลงทะเบียน ดังนั้นถ้าหากเราจะแคร้ก เราจะต้องเริ่มตั้งแต่ด้านล่างสู่ด้านบน ซึ่งก็คือ แสดงกล่องข้อความแล้ว สูงขึ้นไปอีกจะมีการเปรียบเทียบ สูงไปอีกจะมีการรับตัวอักษรที่เราป้อนเข้าไป ดังรูปข้างล่าง ที่ใช้ Debugger ที่มีชื่อว่า Win32 Disassembler Version 8.93



Import Function

เป็นฟังก์ชันที่มีการใช้ในโปรแกรมที่เราใช้ debugger load เข้ามา เช่น โปรแกรมแสดงกล่องข้อความ(messagebox) ก็จะมีการเรียกใช้งานจาก ไฟล์ User32.dll ซึ่ง ถ้าหากเป็นสมัยก่อนเราต้องเขียนโค้ดยืดยาวมากกว่าจะแสดงกล่องข้อความได้ แต่ในปัจจุบันภาษาระดับก้าวหน้ามากขึ้น การแสดงกล่องข้อความจึงเป็นเรื่องง่าย import function นี้มีประโยชน์มากในการแคร้ก เช่น เมื่อเรากดลงทะเบียนโปรแกรม ก็จะมีกล่องข้อความขึ้นมาว่าถูกหรือผิด เราสามารถรู้ว่ามีการใช้งานฟังก์ชั่น แสดงกล่องข้อความที่จุดๆใด สำหรับโปรแกรม Win32 Disassembler นี้ เมื่อเราดับเบิ้ลคลิกที่ ชื่อ function โปรแกรมจะทำการค้นหาเลยว่าที่ใดบ้างมีการใช้ฟังก์ชันที่เราดับเบิ้ลคลิก ดังรูปข้างล่าง



String Data Reference

เป็นที่เก็บ String ของโปรแกรมที่เรา load เข้า debugger , String คือ ข้อความต่างๆที่มีอยู่ในตัวโปรแกรมนั้นๆ เป็นการเอื้อประโยชน์แก่การแคร้กมาก เช่น เมื่อโปรแกรมแสดงกล่องข้อความว่า "Incorrect" เราสามารถเปิดดูใน String data reference ได้ แล้วดับเบิ้ลคลิกที่ string นั้นๆ โปรแกรมก็จะทำการค้นหาว่า มีที่ใดบ้างที่มีการเรียกใช้งาน string หรือ คำๆนั้น ดังรูปข้างล่าง



String

ภายใน Debugger จะแสดงให้เห็นว่า บรรทัดนั้นๆมีการเรียกใช้ String คำว่าอะไรบ้าง

Assembly Address


เป็น เสมือนที่อยู่ของโค้ดๆนั้น assembly address สำหรับ โปรแกรม Win32 Disassembler จะอ่านค่าตั้งแต่ 00401000 คือโค้ด เริ่มตั้งแต่การใช้งานโปรแกรมนี้ โดยการจัดเรียง address จะสังเกตว่า เพิ่ม ทีละไม่เท่ากัน มีสาเหตุมาจาก คำสั่งแต่ละคำสั่ง ซึ่ง จะขึ้น address ใหม่ก็ต่อเมื่อมีการใช้คำสั่งอื่นๆ และจะเอา



E8 8F 0E FB FF เป็นโค้ดในรูปแบบเลขฐาน 16 2ตัวจะนับเป็น 1 ไบต์ มีทั้งหมด 5 ไบต์ จาก address ของโค้ดๆนี้ address คือ 4537B0 ต่อไป ก็จะ +5 เป็น 4537B5 ทั้งนี้ แม้แต่ address ก็เป็นเลขฐาน16ด้วย การบวกลบจะใช้วิธีของเลขฐาน10ไม่ได้

Hex Code

เป็นคำสั่งที่อยู่ในรูปของเลขฐาน 16 hex code 1 ไบต์มักจะแทนคำสั่งได้ 1 คำสั่ง เช่น 75 แทน คำสั่ง JNE (Short (assembly)) และหลัง 1 ไบต์ก็มักจะเป็นการอ้างอิงตำแหน่ง แต่ถ้าหาก มีการ JNE Long ก็มักจะเปลี่ยนคำสั่งทาง hex เป็น 0F 85 สำหรับการ Jne (short) เช่น ในรูปแรก ถ้าเอาaddress ต่อจาก addressที่มีโค้ด jne ไป + ด้วย ไบต์ ต่อหลังJne ก็จะได้ address ที่มีการ jneไป เช่น 004537B5 740C JNE 004537C3 , address ต่อจากโค้ดนี้ = 004537B7 ให้+ด้วยไบต์ต่อจาก 75 คือ 0C จะได้ 004537C3

Assembly Code

จะนำเสนอ code ของ assembly เบื้องต้นที่มีความสำคัญต่อการแคร้ก ดังนี้

JNE = Jump If not Equal กระโดด ถ้าไม่เท่ากัน (75)
JE = Jump If equal กระโดดถ้าเท่ากัน (74)
JG = Jump If greater กระโดดถ้ามากกว่า (7F)
JGE = Jump if greater or equal กระโดดถ้ามากกว่าหรือเท่ากัน (7D)
JB = Jump if Below กระโดดถ้าน้อยกว่า (72)
JBE = Jump if below or equal กระโดดถ้าน้อยกว่าหรือเท่ากัน (76)
JMP = Jump กระโดดโดยไม่มีข้อแม้ (EB)
CALL = Call เป็นการเรียกเข้าไปทำงานอีกส่วนหนึ่ง มักจะตามด้วยคำสั่ง Ret (E8)
Ret = Return จะเป็นการสั่งให้ไปรันโค้ดที่อยู่ใต้ คำสั่ง Call เสมือนกับ จุดวกกลับให้กลับไปทำงานตามเส้นทางเดิม(C3)
CMP = Compare เปรียบเทียบ เช่น cmp Eax,ebx = เปรียบเทียบ สิ่งที่มีอยู่ภายใน Register Eax กับ Ebx ว่าเหมือนกันหรือไม่ ถ้าเหมือนจะใส่ 1 เก็บลงที่ Register ตัวตั้ง (Eax)
Mov = Move เช่น Mov eax,ebx = ดึงข้อมูลจาก register ebx ไปเก็บที่ ตัวตั้ง(eax)

อ่านแล้วอาจจะงงกันบ้างเล็กน้อย ผมจะแสดงเป็น flow chart จำลองให้เห็นหลักๆว่ามันมีการทำงานภายในอย่างไรบ้าง



จากรูปด้านบน เราสามารถใช้เปลี่ยนคำสั่ง จาก JE เป็น JNE ซึ่งเป็นคำสั่งตรงกัน โดยใช้Debugger ได้ เป็นหลักการง่ายๆสำหรับการเปลี่ยนเส้นทางการเกินของโปรแกรม ดังนั้นถ้าหากเราเปลี่ยนเป็น JNE เมื่อมีการเปรียบเทียบจากโค้ดที่เราใส่ไปมั่วๆมันก็จะกระโดด เนื่องจาก JNE กระโดดเมื่อไม่เท่ากัน : )


Jump Reference

Jump Reference มีหน้าที่บอกเราว่า Addressนี้ สามารถ กระโดดมาจากที่ใดบ้าง ดังรูปในหัวข้อ Assembly code ที่ messagebox "Correct" จะแจ้งว่ามีการกระโดดมาจาก address นั้นๆ (Ref from) ดังตัวอย่างในรูปข้างล่าง



หวังว่าบทความนี้จะทำให้ผู้อ่าน มองทะลุปรุโปร่ง เกี่ยวกับ การแคร้กมากขึ้น ในบทความนี้จะเป็นการเกริ่นพื้นฐานให้ สำหรับบทความต่อไป อาจจะนำเสนอเป็นวีดีโอ เกี่ยวกับ การแคร้ก การแก้ไข ด้วยการใช้ W32dasm

โปรแกรมที่ใช้นำเสนอ :

Download BasicCrack.exe


บทความ ที่ 3

อ่านภาษา Assembly เบื้องต้นเพื่ออ่านหลักการทำ Serial

ในบทความบทก่อนได้กล่าวถึง คำสั่งทาง assembly เบื้องต้นแล้ว
ในบทความบทนี้จะอธิบายเกี่ยวกับคำศัพท์และ คำสั่ง ทาง assembler เพิ่มเติม

Register เป็นส่วนประกอบที่สำคัญมากในการแคร้ก รีจีสเตอร์มีหน้าที่ในการจดจำข้อมูลต่างๆ หลักๆ Register มีขนาด 32 Bit (4 Bytes) โดยตั้งแต่ 0-FFFFFFFF (FF = 1 byte = 8 bits F= 15, FF = 255 ,FFFF = 65535, FFFFFFFF = 65535 ^2 =ผลลัพธ์มากสุดที่บรรจุลงใน register ได้ ) มี Registers9 ชนิด คือ


EAX แยกออกไป ได้อีกคือ
AX มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
AH หรือ AL มีขนาด 8 บิต( 1 Byte = FF มีขนาดสูงสุด 255)
EBX
BX มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
BX หรือ BL มีขนาด 8 บิต( 1 Byte = FF มีขนาดสูงสุด 255)
ECX
CX มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
CH หรือ CL มีขนาด 8 บิต( 1 Byte = FF มีขนาดสูงสุด 255)
EDX
DX มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
DH หรือ DL มีขนาด 8 บิต( 1 Byte = FF มีขนาดสูงสุด 255)
ESI
SI มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
EDI
DI มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
EBP
BP มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
ESP
SP มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ
EIP
IP มีขนาด 16บิต (2ไบต์ = FFFF มีขนาดสูงสุด 65535d) แยกออกไปได้อีกคือ

ในบทความนี้จะไม่นำเสนอว่า มันมีหน้าที่อย่างไรบ้าง เพราะเวลาแคร้กมันไม่ได้จำเป็น จำเป็นเพียงแต่ดูคำสั่ง asm ว่ามันทำอะไรกับ registers บ้าง ยกตัวอย่าง


EAX = A0B1C2D3
AX จะเท่ากับ C2D3
AH/Al จะเท่ากับ D3

เช่นมีคำสั่ง mov ebx,al จะเป็นการ นำค่าจาก al ไปไว้ที่ ebx ดังนั้น ebx จะเท่ากับ D3 เพราะเรา mov แค่ al(1 ไบต์)

คำสั่งที่ควรรู้ และสามารถนำไปใช้คิดทำ รหัสลงทะเบียนได้ ( Serial )
And Xor Or Not เป็นคำสั่งในทางตรรกศาสตร์ ในการหาค่า ตัวตั้งกับตัวนำมา and xor or not กัน อธิบายคร่าวๆได้ดังนี้

And ("และ")
จำแค่ว่า ตัวตั้งเป็น 1 ตัวนำมา And เป็น 1 ผลลัพธ์ จะได้ 1 นอกนั้นไม่ว่าตั้งด้วยอะไร นำด้วยอะไรมา and ก็ได้ 0 หมด ดังนี้
1010 And 0101 จะได้ดังนี้

1011 ตัวตั้ง
0101 ตัวนำมา And
0001 นี่คือผลลัพธ์
เปรียบเทียบแต่ละหลัก(บิต) ของตัวตั้งและตัวนำมา and , แต่หากเราจะนำ123 มา and 19 จะต้องเปลี่ยนเป็นฐานสองเสียก่อนได้ดังนี้

01111011 (123)
00010011 (19)
00010011 (19 ดังเดิม)


---------------------------------------------------------------------------------------------------------------------------
Xor
จำไว้ให้ขึ้นใจ เหมือนกันเป็น 0 ต่างกันเป็น 1 เช่น

1010 Xor 0111

1010 ตั้ง
0111 นำมา Xor
1101 คือ ผลลัพธ์

ยกตัวอย่างเป็นตัวเลข
133 Xor 54

1000 0101 (133)
0011 0110 (54)
1011 0011 (179)
----------------------------------------------------------------------------------------------------------------------------
Or "หรือ"

จำไว้สั้นๆ 0 เหมือนกันได้ 0 นอกนั้น 1 หมด
เช่น

1001 1011 ตัวตั้ง
1101 1001 ตัวนำมา Or
1101 1011 ผลลัพธ์

ยกตัวอย่างเป็นเลข

231 Or 189

1110 0111 (231)
1011 1101 (189)
1111 1111 (255)
-------------------------------------------------------------------------------------------------------------------------
Not "ไม่"

จำสั้นๆ ตัวหลัก 1 ผลลัพธ์ ได้ 0 ,ตัวหลัก ศูนย์ ผลลัพธ์ได้ 1
เช่น

1011 1101 ตัวตั้ง

0100 0010 ผลลัพธ์

ADD คือ "+" เช่น ADD EAX,2 = +รีจีสเตอร์ eax ด้วย2 สมมติว่าเดิม eax = 00000004 +กันแล้วผมลัพธ์จะไปตกที่ eax ดังนั้น eax = 00000006
SUB คือ "-" เช่น SUB ECX,5 = - รีจีส์เตอร์ ECX ด้วย 5 สมมติว่าเดิม ECX = 0000000A - กันแล้ว ผลลัพธ์จะตกไปที่ ecx ดังนั้น ecx = 00000005 ( A ของ hex = 10)
------------------------------------------------------------------------------------------------------------------------
หาก จะ And Xor Or Not ด้วยตัวหนังสือ ต้องเปลี่ยนตัวหนังสือ เป็น Binary ก่อนนะ เช่น
a = 97(ascii) = 0110 0001
ถ้าหากจะ And Xor Or Not ฐาน16 หรืออย่างอื่น ให้เปลี่ยนเป็น ฐานสองเสียก่อน แล้วผลลัพธ์ค่อยแปลงเป็น แบบเดิม

ยกตัวอย่างการคิด Serial ของโปรแกรม Ps To Image จะนำ โค้ด assembly มาอธิบายให้ละเอียดดังนี้

00407BEE E85DA20A00 CALL 004B1E50

'ตัวนี้จะเป็นการเรียกไปคำนวนหาจำนวนตัวอักษรที่เราใส่ลงไปในช่อง Serial ทำไมถึงรู้? ได้จากหลักการความน่าจะเป็นเมื่อเราใส่ชื่ออื่นๆจำนวนอักษรต่างกันแล้วก็สังเกตการเปลี่ยนแปลง


00407BF3 59 POP ECX

'ตัวนี้ไม่ขออธิบายนะ ไม่จำเป็น


00407BF4 83F810 CMP EAX,10

'เปรียบเทียบ Register EAX ด้วย 10(ฐาน16 (ฐาน10จะได้ 16)) ตรงนี้คือการเปรียบเทียบจำนวนอักษรของ Serial ที่พิมพ์ลงไปเพื่อลงทะเบียน กับ 16 จะรู้ได้ไงว่า EAX เป็น ที่เก็บจำนวนอักษรที่พิมพ์ลงไปแทน Serial ก็เพราะเราสังเกตไปเรื่อยๆถ้าหากพิมพ์ 0123 , EAXก็จะได้ 00000004 พิมพ์ abcdefg eax = 00000007 สรุปว่าได้มาจากการสังเกตนั่นเอง ถ้าเปรียบเทียบแล้วเท่ากันกับ 16 รีจีสเตอร์ EAX จะถูกเซ็ตให้เป็น 00000001 (เพราะCMP ตั้งด้วย eax ก่อน ถ้า cmp ebx,10 ebx ก็จะถูกเซ็ตค่าลงแทน) ถ้าไม่เท่ากัน EAX = 00000000


00407BF7 7404 JE 00407BFD

'JE ชนิดนี้ เป็นชนิด สั้น (กระโดด ระยะใกล้) สังเกตได้จาก คำสั่งในเลขฐาน16 เป็น 74 ตามด้วยที่จะไป คือ 04 คำนวนได้ดังนี้ 00407BF7+ไบต์ของโค้ดadr +ไบต์ที่อยู่(04) [00407BF7+2+4 = 00407BFD] JE ตัวนี้มีรับค่าเปรียบเทียบมาจาก cmpด้านบน ดังนั้นกระโดดไม่กระโดดขึ้นอยู่กับค่าของ Register EAX


00407BF9 33C0 XOR EAX,EAX

'คำนวนค่า xor eaxด้วย eax เป็นคำสั่งที่ทำให้ดูเท่ เฉยๆ จริงๆมันมีจุดประสงค์คือ ทำให้ EAX เป็น 0 หรือ ลบค่าต่างๆออกจาก EAX นั่นเอง (สมมติว่าใส่เลข Serial ไป 16ตัวพอดีในตอนนี้ eax มีค่า = 00000010)


00407BFB EB2F JMP 00407C2C

'กระโดดไปทำงานที่ 00407C2C จุดนี้จะไปกระโดดใกล้ๆคำสั่ง ret เพื่อ รีเทิร์นกลับไปรัน Adr ใต้ คำสั่ง CALL มาที่นี่ ซึ่งหมายความว่า ถ้า JE ที่ 00407BF7 ไม่กระโดด มันจะมากระโดดตรงนี้แล้วสรุปว่าเราใส่ Serial ผิด เป็นด่านแรกของการตรวจสอบ Serial สำหรับโปรแกรมนี้


00407BFD 0FBE7305 MOVSX ESI,BYTE PTR DS: [EBX+5]

'หลังจากผ่าน call ไปนับอักษร แล้ว EBX = มีค่า ascii = Serial ที่เราใส่ไป เช่นใส่ไปว่า 00000d00000n7000 (คิดมาก่อนแล้ว เลยเอามานำเสนอให้เข้าใจมากขึ้น) คำสั่งบรรทัดนี้ คือ นำอักษรหลักที่ 6 ไปเก็บไว้ที่ Register ESI ( นับศูนย์ขึ้นต้น ดังนั้นจะได้ ตัวที่6 ที่ใส่ไปคือ "d") เขียนเองได้ง่ายๆคือ mov esi,64 (ascii ของ d = 100 hexของ 100 = 64) ตอนนี้ ESI มีค่า = 64


00407C01 8BC6 MOV EAX,ESI

'นำ ค่าจาก ESI (ตอนนี้คือ 64)ไปไว้ที่ EAX


00407C03 0FBE7B0C MOVSX EDI,BYTE PTR DS: [EBX+C]

'นำค่าที่ได้จาก ตัวอักษรของ EBX + C (ตัวที่13 ที่ใส่ก็คือ 7 ascii 7 = 55 hex 55 = 37) ดังนั้น EDI มีค่า 00000037


00407C07 03C7 ADD EAX,EDI

' บวกค่าที่อยู่ใน EAX ด้วยค่าที่อยู่ใน EDI และผลลัพธ์กลับสู่ EAX จาก 00407C01 ให้เอา esi มาไว้ eax = 00000064 + ด้วยค่า edi(37) จะได้ 0000009B ดังนั้น EAX = 0000009B


00407C09 3D 9B000000 CMP EAX,9B

' เปรียบเทียบว่า eax = 9B รึเปล่า ตัว9B ตัวนี้เขากำหนดมาเจาะจงไม่ได้มาจาก register ตัวไหนเขาจะเขียนเป็นค่าไว้เลย จาก 00407C07 เรา+กันแล้วได้ eax = 9Bพอดี ดังนั้นการเปรียบเทียบครั้งนี้ EAX = 1 เพราะมันเปรียบเทียบแล้วเท่ากัน


00407C0E 751A JNE 00407C2A

' ตัวนี้จะกระโดดถ้าหากไม่เท่ากัน (หรือ รีจีสเตอร์เป็น 0) จั้มตัวนี้จะกระโดดออกการคำนวนแล้วไปบอกว่ารีจีสเตอร์เราผิดทันที เป็นการตรวจสอบครั้งที่สองว่า ค่า hexของ ascii ตัวที่ 6+ตัวที่ 13 แล้วได้ 9B หรือไม่ ดังนั้นจาก00407C09 มันเปรียบเทียบแล้วว่าเท่ากัน ดังนั้นเราจึงผ่าน JNE ตัวนี้ไปโดยไม่กระโดด


00407C10 8BCE MOV ECX,ESI

' นำค่าจาก ESI ไปเก็บ ที่ ECX ,จาก ADR 00407BFD ตอนนั้น ESI เรามีค่า 64 เมื่อนำไปเก็บ ECX = 00000064


00407C12 2BCF SUB ECX,EDI

'เอา ECX มาตั้ง แล้ว ลบด้วย EDI (ECX จาก 00407C10 = 00000064 ,EDI จาก 00407C03 มีค่า 00000037) ลบกันแล้วจะได้ 2D (ลบทางhex) ถ้าไม่ถนัดลบทาง hex ให้เปลี่ยน 64 เป็นฐาน10 และเปลี่ยน 37 เปลี่ยนฐาน10 จะได้ 100-55 จะเหลือ 45 และ hex ของ 45 จะได้ 2D ดังนั้น ECX จะได้ผลลัพธ์ = 0000002D


00407C14 8BC1 MOV EAX,ECX

' นำECX ไปเก็บที่ EAX ดังนั้น EAX = 0000002D


00407C16 99 CDQ

' อันนี้ไม่ขออธิบายเพราะไม่จำเป็นสำหรับ serial นี้


00407C17 33C2 XOR EAX,EDX

' ตั้งด้วย EAX Xor ด้วย EDX ผลลัพธ์ ตกไปที่ EAX (จาก 00407C14 eax = 0000002D จาก โค้ดทั้งหมดมาไม่มีเกี่ยวข้องกับ edx แสดงว่า edx = 0) ดังนั้นผลลัพธ์ได้เท่าเดิม eax ได้เท่าเดิม


00407C19 2BC2 SUB EAX,EDX

' ตั้ง eax ลบด้วย edx (2D-0 = 2D) eax มีค่าเท่าเดิม


00407C1B 83C041 ADD EAX,41

' บวก EAX ด้วย 41 (2D+41 = 6E [ 45+65 = 110 (ascii = n) hex = 6E)ผลลัพธ์ EAX= 0000006E


00407C1E 0FBE530B MOVSX EDX,BYTE PTR DS: [EBX+B]

' นำ ตัวอักษรตัวที่ B ใน EBX ไปเก็บว้ใน EDX ( string ใน ebx = 00000d00000n7000) ตัวที่ B = 12 = n (ascii n = 110 hex 110 = 6E)


00407C22 3BC2 CMP EAX,EDX

' ขั้นตอนสุดท้าย เปรียบเทียบ EAX (6E)ด้วยEDX (6E เหมือนกัน) ปรากฎว่าเท่ากัน ดังนั้น eax = 1


00407C24 7504 JNE 00407C2A

' กระโดดถ้าไม่เท่ากัน จะกระโดดไปที่ 00407C2A เพื่อออกนอกกระบวนการและบอกว่า เราลงทะเบียนด้วยโค้ดไม่ถูกต้อง นี่คือ การเปรียบเทียบครั้งสุดท้าย ดังนั้นตัวนี้เราผ่านแบบไม่กระโดด


00407C26 B001 MOV AL,1

' นำ 1 ไปที่ AL ( ไบต์ที่ 1 ของ EAX) EAX= 00000001


00407C28 EB02 JMP 00407C2C

' กระโดดไปที่ 00407C2C โดยไม่ต้องมีเงื่อนไข

AL = 1 เนื้องจาก หลัง การสร้าง serial จริงไปแล้ว ใต้ callที่มาสร้างมันมีการเปรียบเทียบ ว่า al = 1 หรือเปล่า ( เปรียบเทียบตัวที่เราพิมพ์ลงไปกับ serial จริง ดังนั้น TEST AL,AL AL จะได้เท่ากับ 1 คำสั่ง TEST เป็นคำสั่งเปรียบเทียบ เหมือน CMP แต่ส่วนมากคิดว่ามันน่าจะใช้เปรียบเทียบ Register ด้วยกัน

รูปข้างล่าง เป็นโค้ด Assembly ที่ผมแปลให้อ่านทั้งหมดด้านบน



เพื่อเสริมความเข้าใจ มี Flow Chart แสดงขั้นตอนการทำงาน ซึ่ง FC นี้ สร้างมาจาก debugger ชื่อ IDA



ทั้งหมดนี้ อธิบายการอ่าน ภาษา assembly เบื้องต้นเท่านั้น สำหรับบทความต่อไปจะพยายามนำเสนอว่า จะเจอ Address ต่างๆได้ยังไง ขอให้ติดตามชมกันต่อไป

VDO สอนวิธีหาคีย์ใช้เอง Dekaron Pro 5.7








สอนวิธีหาคีย์ใช้เอง Dekaron Pro 5.7 !!!!

Dekaron.exe ตัวเก่าก่อน Patch 07/01/2009

Download

DekaronPro 5.7

Download

ต้องใช้ SND attach process ใช้ olly attach process ไม่ได้

Download

เมื่อเปิด SND ขึ้นมา ให้ไปที่ ตัวเลือก > การแสดงผล > Directories
แล้วก็เปลี่ยนเป็น .\UDD และ .\Plugin ไม่งั้นพอกดใช้งานปุ้บ Error เลยอะ ดูสถานะ SND ด้วยว่ามัน Pause อยู่รึเปล่า ทำให้เป็นเหมือนรูปเลย




เอา ollydbgsnd ไปใว้ที่ drive อะไรก็กด browse ไปหาตามที่ลงเอาไว้

แต่ถ้าเป็นโปรแกรมอื่น ไม่ต้องทำ attach ลากเข้ามาใส่ใน SND ลากมาใส่ อันเดียวกับ Open อะ ที่ 420000 เปลี่ยนเป็นอย่างอื่นก็ได้ พอมาถึง nop แล้วกด F2 พอกลับมาที่ตัวโปรมัน non responding หัยแก้โดยการ กด F9 ที่ SND โปรแกรมจะรัน เพราะขณะที่เราแก้ มัน pause ไว้ และตรง je 412ede ไม่จำเป็นต้องเบรค ตรงนี้ไว้ ไปเบรคแถวๆ 411A25

การแคร้กทำได้หลายรูปแบบ ถ้าจะเอาคีย์ของโปร 5.7 ตัวนี้ก็ทำแบบนี้ แล้วแต่โค้ดที่เขาเขียนมา

Credit By LGRDKA

ไม่มีความคิดเห็น: