DLL, Path, Integrity & Reverse Engineering - Thử giới hạn của cơ chế bảo vệ (1 người xem)

Người dùng đang xem chủ đề này

Kiều Mạnh

I don't program, I beat code into submission!!!
Tham gia
9/6/12
Bài viết
5,691
Được thích
4,184
Giới tính
Nam

Một bài thử nghiệm về DLL, Path, Integrity và Reverse Engineering dành cho những ai thích tìm hiểu giới hạn của cơ chế bảo vệ​

Bạn sẽ bắt đầu từ đâu?​

Đây là một bài thử nghiệm nhỏ dành cho những ai quan tâm đến DLL, Path, Integrity, Reverse Engineering và kỹ thuật phân tích phần mềm trên Windows.

Mục đích của bài test không phải để khẳng định một DLL có thể "chống crack tuyệt đối".

Ngược lại, tôi muốn đặt một câu hỏi đơn giản:

Nếu bạn có trong tay SampleAddin.dll đã được ký và chương trình kiểm tra đi kèm, bạn có thể tìm ra điểm yếu của cơ chế bảo vệ không?
Bạn có thể tự do phân tích và thử nghiệm bằng những công cụ quen thuộc như IDA, Ghidra, x64dbg, WinDbg, PE-bear hoặc bất kỳ công cụ Reverse Engineering nào mà bạn thường sử dụng.


1. Bộ thử nghiệm​

Bộ thử nghiệm gồm hai thành phần chính:

TestSampleAddin.exe
SampleAddin.dll

TestSampleAddin.exe là chương trình console dùng để nạp DLL bằng LoadLibrary, tìm các hàm export bằng GetProcAddress và gọi từng hàm để kiểm tra kết quả.

DLL cung cấp các hàm thử nghiệm:

CalcSum
CalcDiff
CalcProduct
CalcWeightedSum
Ngoài ra, chương trình test cũng kiểm tra sự tồn tại của entry point:

DllGetClassObject
Entry point này chỉ được kiểm tra về mặt export trong bài test hiện tại, không thực hiện đầy đủ quy trình tạo COM object.


2. DLL nguyên vẹn sẽ hoạt động như thế nào?​

Khi SampleAddin.dll còn nguyên vẹn và vượt qua cơ chế kiểm tra Integrity, các hàm được kỳ vọng hoạt động bình thường.

Ví dụ chương trình test gọi:

CalcSum(3, 4)
CalcDiff(3, 4)
CalcProduct(3, 4)
CalcWeightedSum(3, 4, 2)
Các kết quả bình thường được thiết kế tương ứng với logic của DLL.

Mục đích của việc sử dụng nhiều hàm khác nhau là để tránh biến bài test thành một phép kiểm tra đơn giản kiểu:

Integrity OK -> chạy
Integrity FAIL -> return 0
Các hàm được thiết kế với những vị trí và hình thức kiểm tra khác nhau.


3. Điều gì xảy ra nếu DLL bị thay đổi?​

Đây là phần dành cho người thích phân tích.

Bạn có thể thử sửa SampleAddin.dll sau khi DLL đã được ký.

Không nhất thiết phải thay đổi nhiều.

Một byte cũng có thể là đủ để bắt đầu thử nghiệm.

Bạn có thể tự kiểm tra:

  • Thay đổi một byte.
  • Thay đổi instruction.
  • Patch một nhánh điều kiện.
  • Thay đổi giá trị trả về.
  • Thay đổi code thực hiện phép tính.
  • Tìm vị trí Integrity Check.
  • Tìm cách làm cho chương trình tin rằng DLL vẫn hợp lệ.
  • Quan sát sự khác biệt giữa DLL nguyên vẹn và DLL đã bị thay đổi.
Sau mỗi thay đổi, hãy chạy lại:

TestSampleAddin.exe
và quan sát kết quả của từng hàm.


4. Không chỉ có Crack DLL​

Một phần khác của bài test nằm ở Path và DLL Loading.

Chương trình test không đơn giản chỉ giả định rằng tên file là đủ.

Bạn có thể tự đặt ra những câu hỏi như:

Nếu DLL bị di chuyển thì sao?
Nếu có một DLL khác cùng tên thì sao?
Nếu thay đổi thư mục chạy thì sao?
Nếu có một file giả mạo SampleAddin.dll thì sao?
Nếu DLL được nạp từ một vị trí khác với vị trí mà bạn dự kiến thì sao?
Đây là lý do bài test không chỉ tập trung vào việc "patch một instruction".

Path cũng là một phần của bài toán bảo vệ phần mềm.


5. Hãy thử suy nghĩ như một người Reverse Engineer​

Nếu bạn mở DLL bằng IDA hoặc Ghidra, bạn có thể bắt đầu bằng việc xem:

PE Header
Export Table
Imports
Strings
Code Sections
References
Call Graph
Sau đó tìm hiểu:

CalcSum
CalcDiff
CalcProduct
CalcWeightedSum
Các hàm này không được thiết kế hoàn toàn giống nhau.

Có hàm có cơ chế kiểm tra gần đầu hàm.

Có hàm để kết quả kiểm tra tác động trực tiếp vào phép tính.

Có hàm sử dụng giá trị phụ thuộc vào thông tin của sản phẩm.

Có hàm đặt phần kiểm tra sâu hơn trong một hàm nội bộ.

Điều này tạo ra nhiều hướng phân tích khác nhau.


6. Một byte có thể nói lên điều gì?​

Một thử nghiệm rất đơn giản:

Sửa đúng một byte trong DLL rồi chạy lại chương trình.
Sau đó so sánh:

DLL nguyên bản
vs.
DLL đã thay đổi
Bạn có thể kiểm tra:

  • SHA-256.
  • PE structure.
  • Export table.
  • Code flow.
  • Kết quả từng hàm.
  • Phản ứng của Integrity Check.
Điều thú vị không nằm ở việc "sửa được một byte".

Điều thú vị là:

Sau khi một byte bị thay đổi, cơ chế bảo vệ phát hiện điều đó ở đâu và phản ứng như thế nào?

7. Nếu patch được một nhánh thì sao?​

Giả sử bạn tìm được đoạn code quyết định:

Integrity hợp lệ
|
+---- YES
|
+---- NO
Bạn có thể thử phân tích xem việc thay đổi luồng thực thi có làm thay đổi hành vi hay không.

Nhưng đó chưa phải là toàn bộ bài test.

Nếu một điểm kiểm tra bị bypass, hãy tiếp tục đặt câu hỏi:

Các hàm khác có còn được bảo vệ không?
Có điểm kiểm tra thứ hai không?
Có logic nào nằm trong hàm phụ không?
Có thể bypass một điểm nhưng vẫn bị phát hiện ở điểm khác không?
Đây chính là phần tôi muốn dành cho những người có kinh nghiệm Reverse Engineering.


8. Đừng chỉ tìm cách phá chữ ký​

Một chữ ký số hợp lệ không đồng nghĩa với việc toàn bộ hệ thống loading và execution đã an toàn.

Trong thực tế, người phân tích có thể quan tâm đến nhiều lớp khác nhau:

Path
|
v
DLL Loading
|
v
Identity / Signature
|
v
Integrity
|
v
Export
|
v
Function
|
v
Runtime Behaviour
Nếu một lớp có vấn đề, attacker có thể tìm cách đi vòng qua lớp đó thay vì trực tiếp phá cơ chế mật mã.

Vì vậy, bài test này không đặt câu hỏi:

"Bạn có phá được RSA không?"
Mà đặt câu hỏi rộng hơn:

"Bạn có thể khiến chương trình chạy theo cách mà cơ chế bảo vệ không dự kiến hay không?"

9. Bạn được phép thử những gì?​

Trong phạm vi môi trường thử nghiệm của chính bạn, bạn có thể sử dụng các phương pháp phân tích phù hợp với mục đích nghiên cứu.

Ví dụ:

IDA
Ghidra
x64dbg
WinDbg
PE-bear
Detect It Easy
Bạn có thể:

  • Phân tích PE.
  • Phân tích Export.
  • Trace execution.
  • Đặt breakpoint.
  • Quan sát call stack.
  • So sánh DLL trước và sau khi thay đổi.
  • Patch bản thử nghiệm.
  • Thử thay thế DLL.
  • Thử nghiệm Path và DLL loading.
  • Tìm điểm quyết định Integrity.
  • Phân tích sự khác biệt giữa các Guard.
Mục tiêu là hiểu cơ chế hoạt động và tìm ra giới hạn của nó.


10. Tôi đặc biệt muốn xem những cách tiếp cận khác nhau​

Nếu bạn tìm được vấn đề, đừng chỉ nói:

Hãy cho biết bạn đã đi theo hướng nào.

Ví dụ:

Path
-> DLL loading
-> DLL replacement
hoặc:

Reverse Engineering
-> tìm Integrity Check
-> trace call
-> tìm điểm quyết định
-> kiểm tra behaviour
hoặc:

PE analysis
-> Export
-> Entry point
-> References
-> Guard
Mỗi cách tiếp cận đều có giá trị.


11. Nếu bạn tìm được một bypass​

Tôi rất hoan nghênh việc chia sẻ kết quả.

Một báo cáo ngắn có thể gồm:

Công cụ:
IDA / Ghidra / x64dbg / ...

Phương pháp:
Path / Patch / Replacement / Reverse Engineering / ...

DLL nguyên bản:
SHA-256: ...

DLL sau khi thay đổi:
SHA-256: ...

Kết quả trước:
CalcSum = ...
CalcDiff = ...
CalcProduct = ...
CalcWeighted = ...

Kết quả sau:
CalcSum = ...
CalcDiff = ...
CalcProduct = ...
CalcWeighted = ...

Nhận xét:
...
Nếu có screenshot hoặc write-up chi tiết thì càng tốt.


12. Nhưng cũng có thể bạn sẽ tìm thấy một vấn đề khác​

Có thể bạn không cần patch DLL.

Có thể vấn đề nằm ở:

Path
DLL Search
Loading
Export
Verification
Runtime
Hoặc có thể bạn tìm thấy một điểm yếu mà tôi chưa nghĩ đến.

Đó mới chính là điều tôi muốn nhận được từ bài thử nghiệm này.

Không có yêu cầu bạn phải sử dụng một phương pháp cụ thể.

Hãy phân tích theo cách của bạn.


13. Đây không phải lời tuyên bố "không thể crack"​

Tôi muốn nói rõ điều này ngay từ đầu.

Không có mục tiêu tuyên bố:

"SampleAddin.dll không thể crack."
Cũng không có ý định chứng minh rằng một cơ chế bảo vệ nào đó có thể chống lại mọi hình thức Reverse Engineering.

Ngược lại, mục tiêu của bài thử nghiệm là tìm hiểu:

Một cơ chế bảo vệ được thiết kế như thế nào, nó chống lại được những dạng thay đổi nào, và nó còn điểm yếu ở đâu.
Nếu bạn tìm được cách vượt qua, đó là một kết quả có giá trị của bài test, không phải một thất bại cần che giấu.


14. Sau thử nghiệm​

Sau khi có đủ phản hồi, phần tiếp theo có thể sẽ được công bố dưới dạng một technical write-up.

Trong đó có thể phân tích:

  • Những cách bypass đã được tìm thấy.
  • Path attack.
  • DLL replacement.
  • Tamper một byte.
  • Patch branch.
  • Integrity bypass.
  • Những điểm Guard hoạt động tốt.
  • Những điểm Guard chưa tốt.
  • Những bài học có thể áp dụng cho việc bảo vệ DLL thực tế.
Những chi tiết đó sẽ được công bố sau, thay vì đưa ra ngay từ đầu.


Bạn sẽ bắt đầu từ đâu?​

Bạn sẽ kiểm tra Path trước?

Hay mở SampleAddin.dll bằng IDA?

Hay chạy thẳng x64dbg?

Hay tìm cách thay DLL?

Hay đơn giản chỉ sửa một byte và xem chuyện gì xảy ra?

Có thể cách dễ nhất lại không phải là cách bạn nghĩ.


Challenge​

TestSampleAddin.exe và SampleAddin.dll được cung cấp để bạn tự phân tích.

Hãy thử trong môi trường thử nghiệm của bạn.

Phân tích.

Thử nghiệm.

Tìm giới hạn.

Và nếu tìm được điểm yếu, hãy chia sẻ cách bạn đã tìm ra nó.

Path, Integrity hay Crack?

Bạn sẽ bắt đầu từ đâu?

Lưu ý​

Bài thử nghiệm này được xây dựng cho mục đích nghiên cứu, học tập và đánh giá cơ chế bảo vệ phần mềm trên môi trường do người tham gia kiểm soát.

Chỉ thực hiện phân tích và thử nghiệm trên phần mềm, máy tính và môi trường mà bạn có quyền kiểm soát hoặc được phép kiểm thử.

Mã Delphi test DLL như sau

Mã:
program TestSampleAddin;

// ---------------------------------------------------------------------
// TestSampleAddin.dpr
//
// EXE console don gian de test SampleAddin.dll dat cung thu muc.
// Nap DLL bang LoadLibrary, lay dia chi 4 ham xuat khau qua
// GetProcAddress, goi thu tung ham va in ket qua ra man hinh console.
//
// Dong bo voi 4 ham hien co trong uSampleExports.pas (Muc 6 - 4 kieu
// Guard KHAC NHAU VE HINH DANG, khong chi khac ten ham):
//   1. CalcSum(3, 4)          - kieu re nhanh if/exit (DE BI PATCH NHAT)
//   2. CalcDiff(3, 4)         - kieu DET vao phep NHAN
//   3. CalcProduct(3, 4)      - kieu DET vao phep XOR
//   4. CalcWeightedSum(3,4,2) - kieu rai Guard trong ham phu noi bo
//                                (CalcIntermediateStep), khong nam dau ham
//
// Ket qua ky vong khi DLL CON NGUYEN VEN (da ky RSA hop le):
//   CalcSum(3, 4)          = 7
//   CalcDiff(3, 4)         = -1     ((3-4) * 1)
//   CalcProduct(3, 4)      = 12     (co the KHAC 12 neu XOR mask thay doi
//                                    theo Public Key - xem ghi chu duoi)
//   CalcWeightedSum(3,4,2) = 16     (((3+4)*2 + 2) * 1)
//
// Ket qua ky vong khi DLL DA BI TAMPER (sua sau khi ky, hoac chua ky):
//   CalcSum(3, 4)          = 0      (re nhanh, tra ve 0 ro rang)
//   CalcDiff(3, 4)         = 0      ((3-4) * 0)
//   CalcProduct(3, 4)      = gia tri KHAC 12, "co ve hop ly" (khong phai
//                                    0/loi ro rang - dung XOR mask suy ra
//                                    tu 4 byte dau Public Key, muc dich
//                                    gay kho khan cho nguoi phan tich)
//   CalcWeightedSum(3,4,2) = 0      (Guard nam trong ham phu, van tra ve 0)
//
// LUU Y: CalcProduct KHONG the kiem tra bang so co dinh khi tamper, vi
// gia tri XOR mask phu thuoc Public Key cua tung san pham (xem GetXorMask
// trong uIntegrityHeaderV3.pas) - script nay chi kiem tra CalcProduct co
// KHAC 12 hay khong khi nghi ngo tamper, khong assert bang 1 so cu the.
//
// Ham DllGetClassObject (COM entry point) khong test truc tiep o day vi
// can CLSID/IID/Obj thuc su - chi kiem tra co export dung ten hay khong.
//
// Cach dung: copy TestSampleAddin.exe vao cung thu muc voi
// SampleAddin.dll, chay truc tiep tu Command Prompt de xem output.
// ---------------------------------------------------------------------

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows;

type
  TCalcSumFunc = function(A, B: Integer): Integer; stdcall;
  TCalcDiffFunc = function(A, B: Integer): Integer; stdcall;
  TCalcProductFunc = function(A, B: Integer): Integer; stdcall;
  TCalcWeightedSumFunc = function(A, B, Weight: Integer): Integer; stdcall;
  TDllGetClassObjectFunc = function(const CLSID, IID: TGUID; var Obj): HResult; stdcall;

var
  DllPath: string;
  ModuleHandle: THandle;
  CalcSum: TCalcSumFunc;
  CalcDiff: TCalcDiffFunc;
  CalcProduct: TCalcProductFunc;
  CalcWeightedSum: TCalcWeightedSumFunc;
  DllGetClassObject: TDllGetClassObjectFunc;
  ResultSum, ResultDiff, ResultProduct, ResultWeightedSum: Integer;
  TatCaHopLe: Boolean;

// In 1 dong ket qua ra console, kem danh gia PASS/FAIL don gian dua tren
// gia tri ky vong khi DLL con nguyen ven
procedure InKetQua(const TenHam: string; GiaTriThuc, GiaTriKyVong: Integer);
begin
  Write(Format('  %-24s = %-8d', [TenHam, GiaTriThuc]));
  if GiaTriThuc = GiaTriKyVong then
    WriteLn('(khop voi ky vong luc DLL nguyen ven: ', GiaTriKyVong, ')')
  else
    WriteLn('(KHAC ky vong luc DLL nguyen ven: ', GiaTriKyVong, ')');
end;

begin
  try
    DllPath := ExtractFilePath(ParamStr(0)) + 'SampleAddin.dll';

    WriteLn('Dang kiem tra file: ', DllPath);

    if not FileExists(DllPath) then
    begin
      WriteLn('LOI: Khong tim thay SampleAddin.dll cung thu muc voi EXE nay.');
      WriteLn('Hay copy SampleAddin.dll vao cung thu muc roi chay lai.');
      WriteLn;
      WriteLn('Nhan Enter de thoat...');
      ReadLn;
      Exit;
    end;

    WriteLn('Dang nap DLL bang LoadLibrary...');
    ModuleHandle := LoadLibrary(PChar(DllPath));

    if ModuleHandle = 0 then
    begin
      WriteLn('LOI: LoadLibrary that bai. Ma loi Windows: ', GetLastError);
      WriteLn;
      WriteLn('Nhan Enter de thoat...');
      ReadLn;
      Exit;
    end;

    WriteLn('Nap DLL thanh cong. Dang lay dia chi 4 ham xuat khau...');

    try
      @CalcSum := GetProcAddress(ModuleHandle, 'CalcSum');
      @CalcDiff := GetProcAddress(ModuleHandle, 'CalcDiff');
      @CalcProduct := GetProcAddress(ModuleHandle, 'CalcProduct');
      @CalcWeightedSum := GetProcAddress(ModuleHandle, 'CalcWeightedSum');
      @DllGetClassObject := GetProcAddress(ModuleHandle, 'DllGetClassObject');

      if not Assigned(CalcSum) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcSum trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcDiff) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcDiff trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcProduct) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcProduct trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcWeightedSum) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcWeightedSum trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(DllGetClassObject) then
        WriteLn('CANH BAO: Khong tim thay ham DllGetClassObject (khong bat buoc cho test nay).');

      WriteLn('Da tim thay du 4 ham. Dang goi thu tung ham...');
      WriteLn;

      ResultSum := CalcSum(3, 4);
      ResultDiff := CalcDiff(3, 4);
      ResultProduct := CalcProduct(3, 4);
      ResultWeightedSum := CalcWeightedSum(3, 4, 2);

      WriteLn('===============================================');
      WriteLn('KET QUA:');
      InKetQua('CalcSum(3, 4)', ResultSum, 7);
      InKetQua('CalcDiff(3, 4)', ResultDiff, -1);
      InKetQua('CalcProduct(3, 4)', ResultProduct, 12);
      InKetQua('CalcWeightedSum(3,4,2)', ResultWeightedSum, 16);
      WriteLn('===============================================');
      WriteLn;

      // Danh gia tong the: CalcSum/CalcDiff/CalcWeightedSum phai dung
      // chinh xac gia tri ky vong. CalcProduct chi can KHAC 12 la coi
      // nhu "bao hieu tamper" (khong assert bang 1 so cu the vi XOR
      // mask phu thuoc Public Key rieng cua tung san pham).
      TatCaHopLe := (ResultSum = 7) and (ResultDiff = -1) and
        (ResultWeightedSum = 16) and (ResultProduct = 12);

      if TatCaHopLe then
        WriteLn('=> DLL con nguyen ven (chu ky RSA hop le), tat ca ham hoat dong dung nhu thiet ke.')
      else if (ResultSum = 0) and (ResultDiff = 0) and (ResultWeightedSum = 0) then
        WriteLn('=> DLL da bi tamper (chu ky RSA khong hop le), cac ham tu vo hieu hoa dung nhu thiet ke.')
      else
        WriteLn('=> Ket qua KHONG DONG NHAT giua cac ham, can kiem tra lai logic hoac trang thai ky file.');

    finally
      FreeLibrary(ModuleHandle);
    end;

  except
    on E: Exception do
      WriteLn('LOI KHONG MONG DOI: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  WriteLn('Nhan Enter de thoat...');
  ReadLn;
end.

Kết quả thử đúng như sau

1787108906865.png

Can thiệp hoặc chỉnh sửa DLL có thể khiến kết quả sai lệch và các hàm mất tác dụng.

Xin mời những ai thích Path, Reverse Engineering và Crack cùng thử xem cơ chế này chịu được đến đâu!
 

File đính kèm

Khi DLL bị can thiệp chỉnh sửa kết quả sẽ báo như sau

1787116063593.png

Sử dụng Tools sau ghi chuỗi mã hoá vào PE của DLL xong trong DLL sử dụng chính mã đó kiểm tra điều kiện sử dụng hàm

1787116378784.png
 
Có code trong dll thì quá tốt heee !
có dùng không tôi viết hoàn thiện xong úp Tools lên cho dùng thôi .. Tools sẽ tạo ra Một unit chứa mã hoá xong copy Vào DLL do bạn viết sau khi build thành DLL copy DLL đó cho qua Tools ký xác nhận lại là xong

Unit đơn giản như sau
Mã:
unit uRSAPublicKey;

// ---------------------------------------------------------------------
// uRSAPublicKey.pas (V3 - kem Header Blob day du cho obfuscation)
//
// File nay duoc integrity_tool_v2.exe TU DONG SINH RA (-mode=genkey),
// KHONG chinh sua bang tay. Chua PUBLIC KEY va toan bo HEADER BLOB
// (Marker+Version+Flags+CRC+Padding+SigLen rong+Signature rong) - an
// toan de nhung vao DLL phat hanh, KHONG chua private key.
//
// IntegrityHeaderBlob PHAI duoc khai bao dang 1 MANG DUY NHAT (khong
// tach rieng) de dam bao Marker+Version+Flags+CRC+Padding+SigLen+
// Signature nam LIEN TUC trong file DLL da bien dich - day la vung
// se duoc integrity_tool_v2.exe tim (qua Marker) va ghi de (SigLen+
// Signature) sau khi ky.
// ---------------------------------------------------------------------

interface

const
  RSA_PUBLIC_KEY_N: array[0..255] of Byte = (
    $C9, $FA, $68, $A1, $E6, $94, $9C, $ED, $4B, $A4, $89, $A7, $83, $C5, $8C, $8D,
    $20, $3C, $81, $36, $19, $5A, $B5, $D5, $52, $85, $92, $32, $AE, $03, $11, $E5,
    $9D, $AA, $89, $B1, $3F, $A1, $BA, $18, $88, $CE, $95, $51, $7B, $0D, $4E, $62,
    $E9, $27, $47, $A2, $97, $88, $82, $92, $E9, $2F, $A6, $BF, $C7, $98, $F2, $4E,
    $0E, $A9, $3B, $0E, $7C, $F9, $60, $F9, $92, $75, $C5, $40, $D5, $32, $AC, $9F,
    $26, $3F, $71, $E7, $AB, $BE, $A1, $1A, $3C, $9E, $82, $B7, $70, $1A, $75, $DE,
    $C6, $53, $21, $74, $1D, $18, $61, $E9, $47, $A4, $DC, $1B, $29, $D7, $87, $18,
    $3E, $D5, $D4, $BE, $80, $CE, $A7, $2F, $46, $6B, $99, $80, $45, $0B, $45, $98,
    $44, $04, $7C, $36, $CF, $A5, $46, $64, $D5, $F2, $89, $32, $6B, $A9, $74, $7B,
    $95, $8E, $A3, $79, $89, $A9, $60, $5E, $2A, $7D, $C0, $79, $AF, $3C, $87, $98,
    $93, $DA, $2E, $AB, $97, $5D, $86, $69, $DC, $FA, $BC, $20, $DA, $40, $3E, $5D,
    $1D, $81, $48, $F0, $4F, $33, $37, $07, $81, $06, $91, $FB, $B0, $33, $50, $1C,
    $60, $CA, $1A, $A5, $AA, $33, $69, $A8, $90, $5C, $32, $99, $31, $D8, $37, $6A,
    $55, $8C, $CA, $41, $DE, $A6, $FA, $BA, $6B, $6C, $E0, $32, $9C, $8D, $13, $7E,
    $BD, $CB, $3C, $0A, $89, $7B, $E2, $94, $42, $09, $F7, $C4, $E3, $07, $59, $1D,
    $C7, $EB, $39, $92, $3D, $44, $76, $E0, $12, $B2, $A5, $F7, $4C, $1F, $66, $55
  );

  RSA_PUBLIC_KEY_E: Cardinal = 65537;

var
  // Do dai: 320 byte (8 Marker + 2 Version + 2 Flags + 4 CRC + 44 Padding + 4 SigLen + 256 Signature)
  IntegrityHeaderBlob: array[0..319] of Byte = (
    $6C, $DA, $59, $B1, $C7, $6C, $CC, $81, $03, $00, $2C, $00, $97, $C5, $3E, $5C,
    $32, $07, $BD, $E9, $49, $68, $50, $7C, $AF, $F5, $B8, $B7, $4B, $27, $CE, $9E,
    $ED, $F2, $C5, $FC, $99, $42, $61, $3D, $74, $65, $2C, $7E, $A5, $6B, $3D, $77,
    $24, $A8, $09, $5E, $FE, $6F, $60, $76, $AA, $9A, $02, $77, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
  );

implementation

end.
 
Trên GPE này có nhiều thành viện giỏi Path, crack và dịch ngược mã nguồn lắm mờ

"Bạn có thể tự do phân tích và thử nghiệm bằng những công cụ quen thuộc như IDA, Ghidra, x64dbg, WinDbg, PE-bear hoặc bất kỳ công cụ Reverse Engineering nào mà bạn thường sử dụng."

Xin mời phá DLL bài số 1 giúp xong biết những gì phơi bày hết lên đây chơi cho vui
 
Một bài test rất thực tế để hiểu rõ hơn về tính toàn vẹn của file DLL. Cảm ơn bác đã chia sẻ, hóng các pro vào show kỹ năng debug với unpack ở topic này ạ.
 
Tôi không chuyên crack cho native code nhung tôi nghĩ cách dễ nhất để tôi kiểm tra là hay thêm 1 showmessage('thay doi chuoi nay') trong dll đã kí và tôi sẽ sữa chuỗi đó mà nó vẫn xác nhận file chưa bị thay đổi. Tôi chỉ đoán là có thể chứ không khẳng định là không bị phát hiện.
 
Tôi không chuyên crack cho native code nhung tôi nghĩ cách dễ nhất để tôi kiểm tra là hay thêm 1 showmessage('thay doi chuoi nay') trong dll đã kí và tôi sẽ sữa chuỗi đó mà nó vẫn xác nhận file chưa bị thay đổi. Tôi chỉ đoán là có thể chứ không khẳng định là không bị phát hiện.
Thử chỉnh sửa một hay hai hàm trong DLL bài số 1 xong thử thì toàn bộ các hàm khác sẽ trả kết quả sai ngay

hay chỉnh sửa 1 bytes trong DLL cũng vậy có nghĩa có bất kỳ can thiệp chỉnh sửa trong DLL thì kết quả hàm sẽ báo sai trong đó có hàm dễ chỉnh sửa nhất

là CalcSum còn các hàm khác mức độ khó tăng dần vì hàm CalcSum kiểm tra kiểu if not IsValid then

Mã:
function CalcSum(A, B: Integer): Integer; stdcall;

chiều hay mai tôi sẽ làm một DLL theo cách bạn đề xuất

Tôi sử dụng mã nguồn sau thử chỉnh sửa DLL

Mã:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  OD: TOpenDialog;
  FS: TFileStream;
  B: Byte;
  PosSua: Int64;
begin
  OD := TOpenDialog.Create(nil);
  try
    OD.Filter := 'DLL Files (*.dll)|*.dll|All Files (*.*)|*.*';

    if not OD.Execute then
      Exit;

    FS := TFileStream.Create(OD.FileName, fmOpenReadWrite or fmShareExclusive);
    try
      if FS.Size < 1024 then
        raise Exception.Create('File quá nhỏ.');

      // Sửa 1 byte ở giữa file
      PosSua := FS.Size div 2;

      FS.Position := PosSua;
      FS.ReadBuffer(B, 1);

      // Đảo bit thấp nhất
      B := B xor $01;

      FS.Position := PosSua;
      FS.WriteBuffer(B, 1);

      ShowMessage(Format('Đã sửa 1 byte tại Offset = %d (0x%x).',
        [PosSua, PosSua]));
    finally
      FS.Free;
    end;

  finally
    OD.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  TEST_PERCENT: array [0 .. 4] of Integer = (10, 25, 50, 75, 90);
var
  OD: TOpenDialog;
  FS: TFileStream;
  B: Byte;
  PosSua: Int64;
  I: Integer;
  KetQua: string;
begin
  OD := TOpenDialog.Create(nil);
  try
    OD.Filter := 'DLL Files (*.dll)|*.dll|All Files (*.*)|*.*';

    if not OD.Execute then
      Exit;

    FS := TFileStream.Create(OD.FileName, fmOpenReadWrite or fmShareExclusive);
    try
      if FS.Size < 1024 then
        raise Exception.Create('File quá nhỏ.');

      KetQua := 'Đã sửa các vị trí trong DLL:' + sLineBreak + sLineBreak;

      for I := Low(TEST_PERCENT) to High(TEST_PERCENT) do
      begin
        PosSua := FS.Size * TEST_PERCENT[I] div 100;

        FS.Position := PosSua;
        FS.ReadBuffer(B, 1);

        B := B xor $01;

        FS.Position := PosSua;
        FS.WriteBuffer(B, 1);

        KetQua := KetQua + Format('%d%%  -> Offset = %d (0x%x)' + sLineBreak,
          [TEST_PERCENT[I], PosSua, PosSua]);
      end;

      ShowMessage(KetQua);
    finally
      FS.Free;
    end;

  finally
    OD.Free;
  end;
end;

end.

Mã nguồn đầy đủ
 

File đính kèm

Lần chỉnh sửa cuối:
Tiếp theo chủ đề này sẽ có mục cấp License nữa cho đồng bộ và cùng luồng chung vào một chủ đề

đang mô phỏng như sau ... quá trình viết sẽ tinh chỉnh và thay đổi cho phù hợp với thực tế

1787363597698.png

File .lic cấp cho khách hàng sẽ mã hoá như sau

Mã:
LIC1SampleAddin‘oRž2w“‡uãp-V¢÷ rºóW2    ÆÓÿˆjSQŠj   ˜í×TÅ‚G;q~?z©Œa”¥'—Ž5&¼<eJ@_ýJÞË3)Øø¶h/Ô¶‡žK&û”Aáì]ayV¢}I´¼œ/n•&¶3'Ó4“î'ðuŸlκgçu-Í¿‡¾A!XoR+#S‰[?£ôcT‚É¢Ra/îw?álÔÄéźÏoË£Ï
›½¼4ê    ^=ð”ìÓĶö'
uPܬèÇpJ²a(¨rMÙeÛÐný¡,8KèBd8×¼&o´^ùY$¤¯L?ªW–8&Q©U    »ââª
)™¸Ìæâ—‰    Ĺñ,>‡¶Ì0Bµ
 

File đính kèm

Lần chỉnh sửa cuối:
Tôi nghĩ nó sẽ không phát hiện được file đã sữa bạn cứ gửi dùm tôi cái tôi yêu cầu ở trên !
Bài đã được tự động gộp:

Liên kết: https://youtu.be/Ixwlr_TNIlE
đó là bạn tự làm tự test ( hay keo là tự sướng đấy ) ... muốn gì úp DLL của bạn lên đây tôi test cho mọi cái phải có file thật xem video làm gì mất thời gian

trong DLL bài Số 1 tôi có xuất 5 hàm bạn hãy thử trong đó có hai hàm dễ path nhất là CalcSum, và DllGetClassObject vì sử dụng cơ chế if not IsValid then
nên Path dễ nhất hãy thử hàm CalcDiff hay CalcProduct xem thế nào

Mã:
exports
  CalcSum,
  CalcDiff,
  CalcProduct,
  CalcWeightedSum,
  DllGetClassObject;
 
đó là bạn tự làm tự test ( hay keo là tự sướng đấy ) ... muốn gì úp DLL của bạn lên đây tôi test cho mọi cái phải có file thật xem video làm gì mất thời gian

trong DLL bài Số 1 tôi có xuất 5 hàm bạn hãy thử trong đó có hai hàm dễ path nhất là CalcSum, và DllGetClassObject vì sử dụng cơ chế if not IsValid then
nên Path dễ nhất hãy thử hàm CalcDiff hay CalcProduct xem thế nào

Mã:
exports
  CalcSum,
  CalcDiff,
  CalcProduct,
  CalcWeightedSum,
  DllGetClassObject;
Khả năng mình có hạn nên chỉ có thể sữa chuỗi là dễ và trực quan nhất.
Bài đã được tự động gộp:

 

File đính kèm

Khả năng mình có hạn nên chỉ có thể sữa chuỗi là dễ và trực quan nhất.
Bài đã được tự động gộp:
DLL + Hai Exe đó là do bạn viết vậy muốn mình test kiểu gì cũng nói rõ ra chứ

MÌnh mới thử ghi vài bytes vào DLL thì báo như sau

Mã:
TestLoader starting...
Loading: D:\Downloads\TEST\TEST\ProtectedDll.dll
LoadLibrary OK.
All exports found.
------------------------------------------------------------
DLL:
D:\Downloads\TEST\TEST\ProtectedDll.dll
------------------------------------------------------------
IntegrityStatus = 0

BLOCKED: DLL unsigned, modified, or signature invalid.

Integrity Error:
Signature verification failed (Win32=-2146893818)
------------------------------------------------------------

Press ENTER to exit...
 
DLL + Hai Exe đó là do bạn viết vậy muốn mình test kiểu gì cũng nói rõ ra chứ

MÌnh mới thử ghi vài bytes vào DLL thì báo như sau

Mã:
TestLoader starting...
Loading: D:\Downloads\TEST\TEST\ProtectedDll.dll
LoadLibrary OK.
All exports found.
------------------------------------------------------------
DLL:
D:\Downloads\TEST\TEST\ProtectedDll.dll
------------------------------------------------------------
IntegrityStatus = 0

BLOCKED: DLL unsigned, modified, or signature invalid.

Integrity Error:
Signature verification failed (Win32=-2146893818)
------------------------------------------------------------

Press ENTER to exit...
Báo như trên có nghĩa là file đã bị sửa ! Folder mình gửi tetstloader.exe dùng xác nhận file dll có bị sữa không. Loader_testloader.exe là file dùng để sửa dll cụ thể là thông báo chuỗi chinh thành dhinh và đồng thời chạy file testloader nhưng testloader vẫn xác nhận file chưa bị sửa
 
Báo như trên có nghĩa là file đã bị sửa ! Folder mình gửi tetstloader.exe dùng xác nhận file dll có bị sữa không. Loader_testloader.exe là file dùng để sửa dll cụ thể là thông báo chuỗi chinh thành dhinh và đồng thời chạy file testloader nhưng testloader vẫn xác nhận file chưa bị sửa
nói chung Path hay Crack là tôi chịu thua vì có biết gì đâu chỉ test có sao nói vậy thôi

Nhưng cách của tôi là khi DLL bị chỉnh sửa thì kết quả mọi hàm sẽ trả về o hết còn không báo mã lỗi như vậy

và đó cũng là mục đích tôi viết nếu DLL bị can thiệp chỉnh sửa thì Exit êm đẹp thôi còn lại không cần thiết báo gì cả

bạn thử file bài số 1 xem có đúng như vậy không
 
Lần chỉnh sửa cuối:
nói chung Path hay Crack là tôi chịu thua vì có biết gì đâu chỉ test có sao nói vậy thôi

Nhưng cách của tôi là khi DLL bị chỉnh sửa thì kết quả mọi hàm sẽ trả về o hết còn không báo mã lỗi như vậy

và đó cũng là mục đích tôi viết nếu DLL bị can thiệp chỉnh sửa thì Exit êm đẹp thôi còn lại không cần thiết báo gì cả

bạn thử file bài số 1 xem có đúng như vậy không
Vậy nên tôi mới nói build dùm tôi cái dll có showmessage như dll của tôi thì tôi mới kiểm tra dùm được ! Nếu dll đã bị sửa mà vẫn kết quả đúng thì sẽ biết liền !
 
Vậy nên tôi mới nói build dùm tôi cái dll có showmessage như dll của tôi thì tôi mới kiểm tra dùm được ! Nếu dll đã bị sửa mà vẫn kết quả đúng thì sẽ biết liền !
Thử xem có gì báo lại và tôi làm theo cách của tôi ... chi tiết là mã " SHA-256 trước: ...SHA-256 sau: ..."


Cảm ơn mọi người đã quan tâm! Để tất cả cùng chơi công bằng và dễ đối chiếu kết quả, mình bổ sung file test kèm hướng dẫn xác nhận PASS/FAIL.


Đính kèm:


  • SampleAddin.dll (bản đã ký, dùng để bắt đầu)
  • TestSampleAddin.dpr (mã nguồn EXE test — tự build lấy bằng RAD Studio hoặc dùng bản .exe đã compile sẵn nếu có)

Lưu ý: Mình chỉ cung cấp mã nguồn của file test, không cung cấp mã nguồn của SampleAddin.dll. Việc tìm hiểu bên trong DLL là một phần của thử thách.




Cách chơi:


  1. Copy TestSampleAddin.exe (tự build từ .dpr đính kèm) vào cùng thư mục với SampleAddin.dll gốc, chạy thử — đây là baseline "chưa đụng vào gì".
  2. Dùng công cụ bạn thích (IDA, Ghidra, x64dbg, hex editor, PE-bear...) để patch/path/thay thế DLL theo cách bạn muốn.
  3. Chạy lại TestSampleAddin.exe với bản đã sửa.

Cách đọc kết quả — chỉ cần nhìn 2 chỗ:


  • Khối REPORT trên console: tự in sẵn SHA-256 của file + 4 kết quả CalcSum/CalcDiff/CalcProduct/CalcWeightedSum. Copy nguyên khối này vào bài trả lời của bạn (chạy 1 lần với DLL gốc, 1 lần với DLL đã sửa, dán cả 2 khối "trước/sau" là đủ).
  • Popup ShowCalcSumDemo: đây là câu trả lời nhanh nhất, khỏi cần đối chiếu số liệu — bung ra "PASS" tức là bạn đã khiến chương trình chạy đúng dù file đã bị sửa, "FAIL" tức là cơ chế còn chặn.

Bạn được coi là "thành công" khi nào?


  • Thành công toàn phần: cả 4 hàm CalcSum/CalcDiff/CalcProduct/CalcWeightedSum đều ra đúng giá trị gốc (7 / -1 / 12 / 16) SHA-256 của file đã khác so với bản gốc mình cung cấp.
  • Thành công một phần vẫn có giá trị: nếu chỉ 1-2 hàm bị bạn "qua mặt" được còn lại vẫn bị chặn — cứ báo cáo, đó vẫn là dữ liệu hữu ích để đánh giá cơ chế.
  • Nhớ kèm SHA-256 trước/sau (khối REPORT đã tự in sẵn) làm bằng chứng khách quan — không cần chụp màn hình debugger nếu bạn không muốn, nhưng có thì càng thuyết phục.

Format báo cáo gợi ý (như bài gốc):


Công cụ: ...
Phương pháp: Patch / Path / Replacement / Reverse Engineering / ...
SHA-256 trước: ...
SHA-256 sau: ...
Kết quả trước: CalcSum=... CalcDiff=... CalcProduct=... CalcWeighted=...
Kết quả sau: CalcSum=... CalcDiff=... CalcProduct=... CalcWeighted=...
Nhận xét: ...


Tha hồ Path, Patch, thay thế DLL, debug, trace... miễn thử trên máy/môi trường bạn kiểm soát. Không giới hạn cách tiếp cận — mình muốn thấy càng nhiều hướng đi khác nhau càng tốt!


Hình sau là File Tôi đã ký và xác nhận

1787398728367.png

Mã SHA-256 còn nguyên vẹn ban đầu

Mã:
DLL: SampleAddin.dll
SHA-256: f2751b0d6bf7e3afeff40383dfba2321d368102073b1522d62b77e14ff1bb837
Mã nguồn Test kèm theo DLL trong File sau
 

File đính kèm

Thử xem có gì báo lại và tôi làm theo cách của tôi ... chi tiết là mã " SHA-256 trước: ...SHA-256 sau: ..."


Cảm ơn mọi người đã quan tâm! Để tất cả cùng chơi công bằng và dễ đối chiếu kết quả, mình bổ sung file test kèm hướng dẫn xác nhận PASS/FAIL.


Đính kèm:


  • SampleAddin.dll (bản đã ký, dùng để bắt đầu)
  • TestSampleAddin.dpr (mã nguồn EXE test — tự build lấy bằng RAD Studio hoặc dùng bản .exe đã compile sẵn nếu có)

Lưu ý: Mình chỉ cung cấp mã nguồn của file test, không cung cấp mã nguồn của SampleAddin.dll. Việc tìm hiểu bên trong DLL là một phần của thử thách.




Cách chơi:


  1. Copy TestSampleAddin.exe (tự build từ .dpr đính kèm) vào cùng thư mục với SampleAddin.dll gốc, chạy thử — đây là baseline "chưa đụng vào gì".
  2. Dùng công cụ bạn thích (IDA, Ghidra, x64dbg, hex editor, PE-bear...) để patch/path/thay thế DLL theo cách bạn muốn.
  3. Chạy lại TestSampleAddin.exe với bản đã sửa.

Cách đọc kết quả — chỉ cần nhìn 2 chỗ:


  • Khối REPORT trên console: tự in sẵn SHA-256 của file + 4 kết quả CalcSum/CalcDiff/CalcProduct/CalcWeightedSum. Copy nguyên khối này vào bài trả lời của bạn (chạy 1 lần với DLL gốc, 1 lần với DLL đã sửa, dán cả 2 khối "trước/sau" là đủ).
  • Popup ShowCalcSumDemo: đây là câu trả lời nhanh nhất, khỏi cần đối chiếu số liệu — bung ra "PASS" tức là bạn đã khiến chương trình chạy đúng dù file đã bị sửa, "FAIL" tức là cơ chế còn chặn.

Bạn được coi là "thành công" khi nào?


  • Thành công toàn phần: cả 4 hàm CalcSum/CalcDiff/CalcProduct/CalcWeightedSum đều ra đúng giá trị gốc (7 / -1 / 12 / 16) SHA-256 của file đã khác so với bản gốc mình cung cấp.
  • Thành công một phần vẫn có giá trị: nếu chỉ 1-2 hàm bị bạn "qua mặt" được còn lại vẫn bị chặn — cứ báo cáo, đó vẫn là dữ liệu hữu ích để đánh giá cơ chế.
  • Nhớ kèm SHA-256 trước/sau (khối REPORT đã tự in sẵn) làm bằng chứng khách quan — không cần chụp màn hình debugger nếu bạn không muốn, nhưng có thì càng thuyết phục.

Format báo cáo gợi ý (như bài gốc):


Công cụ: ...
Phương pháp: Patch / Path / Replacement / Reverse Engineering / ...
SHA-256 trước: ...
SHA-256 sau: ...
Kết quả trước: CalcSum=... CalcDiff=... CalcProduct=... CalcWeighted=...
Kết quả sau: CalcSum=... CalcDiff=... CalcProduct=... CalcWeighted=...
Nhận xét: ...


Tha hồ Path, Patch, thay thế DLL, debug, trace... miễn thử trên máy/môi trường bạn kiểm soát. Không giới hạn cách tiếp cận — mình muốn thấy càng nhiều hướng đi khác nhau càng tốt!


Hình sau là File Tôi đã ký và xác nhận

View attachment 312445

Mã SHA-256 còn nguyên vẹn ban đầu

Mã:
DLL: SampleAddin.dll
SHA-256: f2751b0d6bf7e3afeff40383dfba2321d368102073b1522d62b77e14ff1bb837
Mã nguồn Test kèm theo DLL trong File sau
Tôi đã patch thông báo 'MARKER-GOC-CHUA-BI-SUA-000000' thành 'MARKER-TOI-DA-SUA-FILE-000000' bằng cách chạy file Loader_TestSampleAddin.exe kết quả
Capture.PNG
 

File đính kèm

Tôi đã patch thông báo 'MARKER-GOC-CHUA-BI-SUA-000000' thành 'MARKER-TOI-DA-SUA-FILE-000000' bằng cách chạy file Loader_TestSampleAddin.exe kết quả
View attachment 312447
Bạn nghĩ sao ấy chứ tôi yêu cầu Path DLL và cung cấp mã Test luôn cho bạn xong Bạn úp Exe ai tin nổi

ý nói cái hình sau trong cái Exe của bạn nếu giả thiết bạn bịa ra ai tin

1787409846674.png

Thử Path chỉnh sửa hàm DLL xong úp mã test lên đây xem
 
Bạn nghĩ sao ấy chứ tôi yêu cầu Path DLL và cung cấp mã Test luôn cho bạn xong Bạn úp Exe ai tin nổi

ý nói cái hình sau trong cái Exe của bạn nếu giả thiết bạn bịa ra ai tin

View attachment 312449

Thử Path chỉnh sửa hàm DLL xong úp mã test lên đây xem
Nếu không tin bạn có thể thêm một var mamay trong dll của bạn để nó tự show mamay trong message tôi chỉ sửa phần chuỗi phía trước như 'mamay của bạn là' + mamay !
Bài đã được tự động gộp:

Với lại nếu tôi bịa tạo 1 message thì sao message của bạn không hiện ? Đã test thì phải tin kết quả rằng dll đó có thể pass được khả năng kiểm tra tính toàn vẹn của file !
 
Lần chỉnh sửa cuối:
Nên chia bài toán để đỡ mất đỡ mất sức ví dụ bài toán số 1 tạo 1 file dll và chị kiểm tra tính toàn vẹn của File đó cho đỡ mất sức ví dụ bài toán số 1 tạo 1 file dll rồi kiểm tra tính toán việc toàn vẹn của file đó. Bài toán số 2 là 1 ví dụ nhỏ của 1 chương trình để kiểm tra việc bẻ khóa. Hiện tại tập tin mà bạn gửi vừa kiểm tra trong file thực thi và file LL như vậy và bẻ khóa sẽ rất tốn thời gian cho 1 thử thách nhỏ.
 
ai tham gia chủ đề này theo bài số 1 hoặc bài số 17 thì tham gia còn không vui lòng lập thớt khác mà bịa chuyện và dẫn dắt tào lao rác rưởi làm loãng chủ đề này

Xin cảm ơn
 
Hàm calcdiff
Mã:
[CODE]function CalcDiff(A, B: Integer): Integer;

var

  X: Integer;

begin

  X := Func38A0;
if x <> 0 then
  Result := (A - B) * X;
else
  Result := 0;

end;



function Func38A0: Integer;

begin

  if Func3800 <> 0 then

    Result := 1

  else

    Result := 0;

end;
[/CODE]
Bài đã được tự động gộp:

Mã:
function CalcSum(A, B: Integer): Integer;
begin
  if Func3880 then
    Result := A + B
  else
    Result := 0;
end;
Bài đã được tự động gộp:

Mã:
function CalcProduct(A, B: Integer): Integer;
var
  X: Integer;
begin
  X := Func38C0;
  Result := (A * B) xor X;
end;
function Func38C0: Cardinal;
var
  P: PByte;
begin
  if Func3840 then
  begin
    Result := 0;
    Exit;
  end;

  P := GPointer;

  Result :=
      Cardinal(P[0])
      or (Cardinal(P[1]) shl 8)
      or (Cardinal(P[2]) shl 16)
      or (Cardinal(P[3]) shl 24);
end;
 
Lần chỉnh sửa cuối:
hàm cuối
Mã:
function CalcWeightedSum(A, B, C: Integer): Integer;
begin
if Func38A0 <> 0 then
  Result := C * (A + B + 1)
else
  Result := 0;
end;

function Func38A0: Integer;
begin
  if Func3800 then
    Result := 1
  else
    Result := 0;
end;


;
Bài đã được tự động gộp:

Đó là logic các hàm trong dll việc patch sẽ kiểm tra sau !
 
Lần chỉnh sửa cuối:
Tôi đã làm 1 patch hàm calsum.
kiểm tra dll của bạn tôi đã sữa 1 byte tại đây.Capture.PNG
Chạy file crack là Loader_TestSampleAddin.exe kết quả sẽ như sau
Capture.PNG
 

File đính kèm

Tôi đã làm 1 patch hàm calsum.
kiểm tra dll của bạn tôi đã sữa 1 byte tại đây.View attachment 312451
Chạy file crack là Loader_TestSampleAddin.exe kết quả sẽ như sau
View attachment 312452
lại lung tung linh tinh nữa tôi keo crack DLL xong bạn đóng gói vào Exe của bạn úp lên nói với mấy tay gà code hay sao

Trong Exe ai biết mô phỏng gì muốn chứng minh bạn có khả năng đó chơi như tôi vậy cung cấp cả mã test nữa ... chơi bài ngữa như vậy mới đang chơi còn không thì thôi tốt nhất nên dừng lại
 
Mã nguồn để test không thể post vì nếu ai đó đem dùng có thể crack phần mềm khác . Tôi sẽ làm một video trong ollydbug và bạn có thể tự kiểm tra.
 
Mã nguồn để test không thể post vì nếu ai đó đem dùng có thể crack phần mềm khác . Tôi sẽ làm một video trong ollydbug và bạn có thể tự kiểm tra.
Vậy Thôi dừng lại đề nghị bạn lập chủ đề khác bàn luận chủ đề của bạn ... còn chủ đề này theo mục đích bài số 1 và bài số 17

Chỉ Path hay Crack DLL và công bố nguồn thử chi tiết như sau để người tham gia test tự build Exe và thử thực tế trên chính máy của họ

Mã:
program TestSampleAddin;

// ---------------------------------------------------------------------
// TestSampleAddin.dpr
//
// EXE console don gian de test SampleAddin.dll dat cung thu muc.
// Nap DLL bang LoadLibrary, lay dia chi cac ham xuat khau qua
// GetProcAddress, goi thu tung ham va in ket qua ra man hinh console.
//
// LUU Y (ban cong khai cho nguoi test/crack tren dien dan): file nay
// CHI la EXE test doc lap, KHONG phai ma nguon cua SampleAddin.dll.
// Khong co ma nguon DLL nao duoc cung cap kem theo - nguoi test chi
// nhan file .dll da bien dich + file .dpr nay de tu build EXE test
// (hoac chay TestSampleAddin.exe da bien dich san, neu co).
//
// Dong bo voi 6 ham hien co trong uSampleExports.pas (Muc 6 - nhieu
// kieu Guard KHAC NHAU VE HINH DANG, khong chi khac ten ham):
//   1. CalcSum(3, 4)          - kieu re nhanh if/exit (DE BI PATCH NHAT)
//   2. CalcDiff(3, 4)         - kieu DET vao phep NHAN
//   3. CalcProduct(3, 4)      - kieu DET vao phep XOR
//   4. CalcWeightedSum(3,4,2) - kieu rai Guard trong ham phu noi bo
//                                (CalcIntermediateStep), khong nam dau ham
//   5. ShowMarkerDemo         - ham "flag" rieng, kiem tra patch 1 CHUOI
//                                TINH doc lap, tu hien MessageBox (khong
//                                tra ve gia tri cho console doc duoc)
//   6. ShowCalcSumDemo        - ham "tu kiem tra", goi thang vao CalcSum
//                                that (khong phai logic rieng) va tu hien
//                                MessageBox PASS/FAIL
//
// Ket qua ky vong khi DLL CON NGUYEN VEN (da ky RSA hop le):
//   CalcSum(3, 4)          = 7
//   CalcDiff(3, 4)         = -1     ((3-4) * 1)
//   CalcProduct(3, 4)      = 12     (co the KHAC 12 neu XOR mask thay doi
//                                    theo Public Key - xem ghi chu duoi)
//   CalcWeightedSum(3,4,2) = 16     (((3+4)*2 + 2) * 1)
//   ShowMarkerDemo         - MessageBox tieu de "Integrity OK", noi dung
//                            la chuoi goc "MARKER-GOC-CHUA-BI-SUA-000000"
//   ShowCalcSumDemo        - MessageBox "PASS - CalcSum(3,4) = 7 ..."
//
// Ket qua ky vong khi DLL DA BI TAMPER (sua sau khi ky, hoac chua ky,
// va Guard van con hoat dong dung thiet ke):
//   CalcSum(3, 4)          = 0      (re nhanh, tra ve 0 ro rang)
//   CalcDiff(3, 4)         = 0      ((3-4) * 0)
//   CalcProduct(3, 4)      = gia tri KHAC 12, "co ve hop ly" (khong phai
//                                    0/loi ro rang - dung XOR mask suy ra
//                                    tu 4 byte dau Public Key, muc dich
//                                    gay kho khan cho nguoi phan tich)
//   CalcWeightedSum(3,4,2) = 0      (Guard nam trong ham phu, van tra ve 0)
//   ShowMarkerDemo         - MessageBox tieu de "ShowMarkerDemo", noi
//                            dung "Integrity FAIL - khong hien marker"
//   ShowCalcSumDemo        - MessageBox "FAIL - CalcSum(3,4) = 0 ..."
//
// Neu nguoi test da PATCH VO HIEU HOA duoc Guard (khong chi sua ngau
// nhien mot cho khac trong file):
//   - CalcSum/CalcDiff/CalcWeightedSum se KHONG con tra ve 0 nua ma tra
//     ve gia tri dung nhu chua bi tamper, DU FILE DA BI SUA O CHO KHAC.
//   - ShowCalcSumDemo se hien "PASS - ... = 7" mac du DLL da bi sua ->
//     day la BANG CHUNG khach quan, ro rang nhat cho biet Guard kieu
//     if/exit (Kieu 1) cua CalcSum da bi vo hieu hoa. Nguoi test chi
//     can nhin popup nay la biet minh da crack thanh cong, khong can
//     doi chieu so lieu console.
//   - Neu chi patch rieng chuoi MARKER_TEXT ma CHUA vo hieu hoa duoc
//     Guard, ShowMarkerDemo van bao "Integrity FAIL" - tuc patch chuoi
//     khong dong nghia voi vo hieu hoa duoc co che bao ve.
//
// LUU Y: CalcProduct KHONG the kiem tra bang so co dinh khi tamper, vi
// gia tri XOR mask phu thuoc Public Key cua tung san pham (xem GetXorMask
// trong uIntegrityHeaderV3.pas) - script nay chi kiem tra CalcProduct co
// KHAC 12 hay khong khi nghi ngo tamper, khong assert bang 1 so cu the.
//
// Ham DllGetClassObject (COM entry point) khong test truc tiep o day vi
// can CLSID/IID/Obj thuc su - chi kiem tra co export dung ten hay khong.
//
// ShowMarkerDemo va ShowCalcSumDemo la thu tuc (procedure), KHONG tra ve
// gia tri cho chuong trinh goi doc duoc - ket qua PASS/FAIL/chuoi marker
// hien truc tiep qua MessageBox (popup rieng), nguoi chay EXE nay phai
// TU QUAN SAT popup hien ra, khong xuat hien tren console.
//
// Cach dung: copy TestSampleAddin.exe vao cung thu muc voi
// SampleAddin.dll, chay truc tiep tu Command Prompt de xem output.
//
// TINH NANG REPORT TU DONG (danh cho nguoi tham gia thu thach dien dan):
// EXE nay tu tinh SHA-256 cua file .dll dang test (dung System.Hash
// chuan cua Delphi, doc lap voi co che RSA/SHA-256 noi bo cua DLL) va
// in san 1 khoi report theo dung mau da neu trong bai dang dien dan.
// Chay EXE 2 lan (1 lan voi DLL goc, 1 lan voi DLL da patch), ghep 2
// khoi report lai thanh phan "truoc/sau" trong bai bao cao, khong can
// tu go tay SHA-256 hay ket qua.
// ---------------------------------------------------------------------

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes,
  System.Hash,
  Winapi.Windows;

type
  TCalcSumFunc = function(A, B: Integer): Integer; stdcall;
  TCalcDiffFunc = function(A, B: Integer): Integer; stdcall;
  TCalcProductFunc = function(A, B: Integer): Integer; stdcall;
  TCalcWeightedSumFunc = function(A, B, Weight: Integer): Integer; stdcall;
  TDllGetClassObjectFunc = function(const CLSID, IID: TGUID; var Obj): HResult; stdcall;
  TShowMarkerDemoProc = procedure; stdcall;
  TShowCalcSumDemoProc = procedure; stdcall;

var
  DllPath: string;
  ModuleHandle: THandle;
  CalcSum: TCalcSumFunc;
  CalcDiff: TCalcDiffFunc;
  CalcProduct: TCalcProductFunc;
  CalcWeightedSum: TCalcWeightedSumFunc;
  DllGetClassObject: TDllGetClassObjectFunc;
  ShowMarkerDemo: TShowMarkerDemoProc;
  ShowCalcSumDemo: TShowCalcSumDemoProc;
  ResultSum, ResultDiff, ResultProduct, ResultWeightedSum: Integer;
  TatCaHopLe: Boolean;
  SHA256Hex: string;

// In 1 dong ket qua ra console, kem danh gia PASS/FAIL don gian dua tren
// gia tri ky vong khi DLL con nguyen ven
procedure InKetQua(const TenHam: string; GiaTriThuc, GiaTriKyVong: Integer);
begin
  Write(Format('  %-24s = %-8d', [TenHam, GiaTriThuc]));
  if GiaTriThuc = GiaTriKyVong then
    WriteLn('(khop voi ky vong luc DLL nguyen ven: ', GiaTriKyVong, ')')
  else
    WriteLn('(KHAC ky vong luc DLL nguyen ven: ', GiaTriKyVong, ')');
end;

// Tinh SHA-256 cua file DLL dang test, dung THashSHA2 chuan cua Delphi
// RTL (System.Hash) - KHONG lien quan den co che RSA/SHA-256 noi bo cua
// chinh DLL (uSHA256.pas trong IntegrityGuardCore). Muc dich: co 1 cach
// tinh hash DOC LAP, ben ngoai, de nguoi test dinh danh chinh xac phien
// ban file .dll ho dang cam tren tay, dung dinh dang bao cao (SHA-256
// truoc/sau) da neu trong bai dang dien dan.
//
// QUAN TRONG: phai doc NOI DUNG FILE qua TFileStream roi bam - KHONG
// duoc goi THashSHA2.GetHashString(FilePath, ...) vi overload do bam
// TRUC TIEP CHUOI KY TU cua tham so dau vao (tuc bam chinh duong dan
// dang la text), khong doc file. Loi nay tung khien 2 lan test (truoc
// va sau khi ky) ra CUNG 1 SHA-256 du noi dung file da khac nhau hoan
// toan - vi duong dan file (chuoi) khong doi giua 2 lan chay.
function TinhSHA256File(const FilePath: string): string;
var
  FS: TFileStream;
begin
  FS := TFileStream.Create(FilePath, fmOpenRead or fmShareDenyWrite);
  try
    Result := THashSHA2.GetHashString(FS, THashSHA2.TSHA2Version.SHA256);
  finally
    FS.Free;
  end;
end;

begin
  try
    DllPath := ExtractFilePath(ParamStr(0)) + 'SampleAddin.dll';

    WriteLn('Dang kiem tra file: ', DllPath);

    if not FileExists(DllPath) then
    begin
      WriteLn('LOI: Khong tim thay SampleAddin.dll cung thu muc voi EXE nay.');
      WriteLn('Hay copy SampleAddin.dll vao cung thu muc roi chay lai.');
      WriteLn;
      WriteLn('Nhan Enter de thoat...');
      ReadLn;
      Exit;
    end;

    WriteLn('Dang nap DLL bang LoadLibrary...');
    ModuleHandle := LoadLibrary(PChar(DllPath));

    if ModuleHandle = 0 then
    begin
      WriteLn('LOI: LoadLibrary that bai. Ma loi Windows: ', GetLastError);
      WriteLn;
      WriteLn('Nhan Enter de thoat...');
      ReadLn;
      Exit;
    end;

    WriteLn('Nap DLL thanh cong. Dang lay dia chi cac ham xuat khau...');

    try
      @CalcSum := GetProcAddress(ModuleHandle, 'CalcSum');
      @CalcDiff := GetProcAddress(ModuleHandle, 'CalcDiff');
      @CalcProduct := GetProcAddress(ModuleHandle, 'CalcProduct');
      @CalcWeightedSum := GetProcAddress(ModuleHandle, 'CalcWeightedSum');
      @DllGetClassObject := GetProcAddress(ModuleHandle, 'DllGetClassObject');
      @ShowMarkerDemo := GetProcAddress(ModuleHandle, 'ShowMarkerDemo');
      @ShowCalcSumDemo := GetProcAddress(ModuleHandle, 'ShowCalcSumDemo');

      if not Assigned(CalcSum) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcSum trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcDiff) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcDiff trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcProduct) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcProduct trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(CalcWeightedSum) then
      begin
        WriteLn('LOI: Khong tim thay ham CalcWeightedSum trong DLL (co the ten export sai).');
        Exit;
      end;
      if not Assigned(DllGetClassObject) then
        WriteLn('CANH BAO: Khong tim thay ham DllGetClassObject (khong bat buoc cho test nay).');
      if not Assigned(ShowMarkerDemo) then
        WriteLn('CANH BAO: Khong tim thay ham ShowMarkerDemo (khong bat buoc cho test nay).');
      if not Assigned(ShowCalcSumDemo) then
        WriteLn('CANH BAO: Khong tim thay ham ShowCalcSumDemo (khong bat buoc cho test nay).');

      WriteLn('Da tim thay du ham bat buoc. Dang goi thu tung ham...');
      WriteLn;

      ResultSum := CalcSum(3, 4);
      ResultDiff := CalcDiff(3, 4);
      ResultProduct := CalcProduct(3, 4);
      ResultWeightedSum := CalcWeightedSum(3, 4, 2);

      WriteLn('===============================================');
      WriteLn('KET QUA (cac ham co gia tri tra ve, doc truc tiep tren console):');
      InKetQua('CalcSum(3, 4)', ResultSum, 7);
      InKetQua('CalcDiff(3, 4)', ResultDiff, -1);
      InKetQua('CalcProduct(3, 4)', ResultProduct, 12);
      InKetQua('CalcWeightedSum(3,4,2)', ResultWeightedSum, 16);
      WriteLn('===============================================');
      WriteLn;

      // Danh gia tong the: CalcSum/CalcDiff/CalcWeightedSum phai dung
      // chinh xac gia tri ky vong. CalcProduct chi can KHAC 12 la coi
      // nhu "bao hieu tamper" (khong assert bang 1 so cu the vi XOR
      // mask phu thuoc Public Key cua tung san pham).
      TatCaHopLe := (ResultSum = 7) and (ResultDiff = -1) and
        (ResultWeightedSum = 16) and (ResultProduct = 12);

      if TatCaHopLe then
        WriteLn('=> DLL con nguyen ven (chu ky RSA hop le), tat ca ham hoat dong dung nhu thiet ke.')
      else if (ResultSum = 0) and (ResultDiff = 0) and (ResultWeightedSum = 0) then
        WriteLn('=> DLL da bi tamper (chu ky RSA khong hop le), cac ham tu vo hieu hoa dung nhu thiet ke.')
      else
        WriteLn('=> Ket qua KHONG DONG NHAT giua cac ham, can kiem tra lai logic hoac trang thai ky file.');

      WriteLn;
      SHA256Hex := TinhSHA256File(DllPath);

      // ---------------------------------------------------------------
      // KHOI REPORT TU DONG - dung dinh dang da neu trong bai dang dien
      // dan (muc "Neu ban tim duoc mot bypass"). Nguoi test chay EXE nay
      // 2 LAN: 1 lan voi DLL GOC (chua sua), 1 lan voi DLL DA PATCH, roi
      // GHEP 2 khoi report lai (phan "truoc" tu lan 1, phan "sau" tu lan
      // 2) thanh 1 bai bao cao hoan chinh de dang len dien dan - khong
      // can tu go tay SHA-256 hay ket qua, giam sai sot khi chep tay.
      //
      // Report CHI dua tren 4 ham nghiep vu da cong khai (CalcSum/Diff/
      // Product/WeightedSum) + SHA-256 file - KHONG in ra bat ky thong
      // tin noi bo nao ve cach Guard hoat dong ben trong (vi du: khong
      // co dong nao ghi "Group A/B/C", "RSA", "CRC section .text"...).
      // Ly do: nguoi test phai TU minh tim hieu co che qua Reverse
      // Engineering, cong cu nay chi ghi lai KET QUA QUAN SAT DUOC TU
      // BEN NGOAI (dung vai tro nhu 1 "oscilloscope" trung lap), khong
      // dong vai tro "tra loi ho" cau truc ben trong dang duoc thu
      // nghiem do do ben vung.
      // ---------------------------------------------------------------
      WriteLn('===============================================');
      WriteLn('REPORT (copy khoi duoi day de dang len dien dan):');
      WriteLn('===============================================');
      WriteLn('DLL: ', ExtractFileName(DllPath));
      WriteLn('SHA-256: ', SHA256Hex);
      WriteLn('CalcSum(3,4) = ', ResultSum);
      WriteLn('CalcDiff(3,4) = ', ResultDiff);
      WriteLn('CalcProduct(3,4) = ', ResultProduct);
      WriteLn('CalcWeightedSum(3,4,2) = ', ResultWeightedSum);
      if TatCaHopLe then
        WriteLn('Trang thai quan sat duoc: TAT CA 4 ham tra ve dung gia tri ky vong luc nguyen ven (7 / -1 / 12 / 16).')
      else if (ResultSum = 0) and (ResultDiff = 0) and (ResultWeightedSum = 0) then
        WriteLn('Trang thai quan sat duoc: CA 3 ham CalcSum/CalcDiff/CalcWeightedSum bi chan (tra ve 0).')
      else
        WriteLn('Trang thai quan sat duoc: KET QUA HON HOP - mot so ham dung ky vong, mot so ham bi chan.');
      WriteLn('===============================================');
      WriteLn;
      WriteLn('===============================================');
      WriteLn('KET QUA (cac ham TU HIEN MESSAGEBOX - khong doc duoc tren');
      WriteLn('console, hay QUAN SAT POPUP hien ra sau moi dong duoi day):');
      WriteLn('===============================================');

      if Assigned(ShowMarkerDemo) then
      begin
        WriteLn('Dang goi ShowMarkerDemo... (xem popup)');
        ShowMarkerDemo;
        WriteLn('  -> Neu popup hien "Integrity FAIL": Guard van con chan.');
        WriteLn('  -> Neu popup hien chuoi da sua (khac "MARKER-GOC-CHUA-BI-SUA-000000"):');
        WriteLn('     ban da vo hieu hoa duoc Guard, khong chi patch rieng chuoi.');
      end;

      WriteLn;

      if Assigned(ShowCalcSumDemo) then
      begin
        WriteLn('Dang goi ShowCalcSumDemo... (xem popup)');
        ShowCalcSumDemo;
        WriteLn('  -> Popup "PASS - CalcSum(3,4) = 7": ban DA CRACK THANH CONG');
        WriteLn('     Guard cua CalcSum, du file DLL da bi sua o bat ky cho nao.');
        WriteLn('  -> Popup "FAIL - CalcSum(3,4) = 0": Guard van con hoat dong,');
        WriteLn('     chua patch duoc.');
      end;

    finally
      FreeLibrary(ModuleHandle);
    end;

  except
    on E: Exception do
      WriteLn('LOI KHONG MONG DOI: ', E.ClassName, ': ', E.Message);
  end;

  WriteLn;
  WriteLn('Nhan Enter de thoat...');
  ReadLn;
end.

Bất cứ ai biết sử dụng Delphi dựa vào mã test này cũng mô phỏng lại test như thật xong cung cấp Exe

Tôi không yêu cầu các bạn gửi source code crack.
Tôi cũng không cần bất cứ EXE nào do các bạn tự viết hoặc upload kèm theo.
Chỉ cần cung cấp DLL đã chỉnh sửa, sau đó tôi sẽ dùng chính TestSampleAddin
/source đã công bố
để kiểm chứng độc lập.
Các bạn có thể tự build, tự test và tự xác nhận kết quả trước khi gửi DLL.

DLL vượt qua đúng bộ test công khai thì tôi công nhận crack thành công.
 
Lần chỉnh sửa cuối:
Như thế này mà chưa thuyết phục được bạn thì mình cũng bó tay bó chân !
Liên kết: https://youtu.be/WzUEZGPV1sE

File dll đã patch tôi để bên dưới
Chính xác Patch thành công ... cảm ơn Bạn để Tôi tính toán lại có lẽ vài ngày chi đó úp lại File nhờ bạn patch lại thêm một lần nữa

nếu Patch thành công thì có lẽ bỏ luôn kỹ thuật này không bao giờ nhắc lại nữa
 
Chính xác Patch thành công ... cảm ơn Bạn để Tôi tính toán lại có lẽ vài ngày chi đó úp lại File nhờ bạn patch lại thêm một lần nữa

nếu Patch thành công thì có lẽ bỏ luôn kỹ thuật này không bao giờ nhắc lại nữa
tôi cũng cố thôi chứ không chuyên !
 

Bài viết mới nhất

Back
Top Bottom