program Project32;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows;

const TEST_ENCRYPT_DATA_SIZE = 16;
var
  g_arr: Integer = 10;
  g_myName: string = ' ';
  g_test_x: array[1..16] of Byte  = ($1, $2,$3, $4, $5,$6, $7, $8 ,$9, $10, $11,$12, $13, $14,$15, $16);


function VBProtectBegin(a: PAnsiChar): Integer; stdcall; external 'Virbox32.dll';
function VBProtectEnd:Integer; stdcall; external 'Virbox32.dll';
function VBVirtualizeBegin(a: PAnsiChar): Integer; stdcall; external 'Virbox32.dll';
function VBProtectDecrypt(a: PAnsiChar;b: PAnsiChar;len:Integer): Integer; stdcall; external 'Virbox32.dll';


PROCEDURE HEXDUMP(buff_in:PBYTE;
              len:Integer);

var
  i,j,cur,linemax,nprinted           :Integer;
  flag                               :BOOL;
  testStr                            :string;
  buff                               :ARRAY[1..4096] of BYTE;
begin
  i := 0;
  j := 0;
  cur := 0;
  linemax := 0;
  nprinted := 0;


  if 0 = len then
  begin
    exit;
  end;

  for i := 1 to len do
  begin
    buff[i] := buff_in^;
    Inc(buff_in,1);
  end;

  i := 0;
  testStr := Format('hex_view = %u bytes'+#13#10+'offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F'+#13#10,[len]);
  Write(testStr);
  flag := TRUE;
  Repeat
    testStr := Format('%.4x | ',[(nprinted div 16)]);
    Write(testStr);
    if nprinted >= len then
    begin
      flag := FALSE;
      break;
    end;
    linemax := 15;
    for j := 0 to linemax do
    begin
      cur := i + j;
      if cur >= len then
      begin
        flag := FALSE;
        Write('   ');
      end
      else
      begin
        testStr := Format('%.2x ',[buff[cur]]);
        Write(testStr);
        nprinted := nprinted + 1;
      end;
    end;

    Writeln('| ');
    for j := 0 to linemax do
    begin
      cur := i + j;
      if cur >= len then
      begin
        flag := FALSE;
        break;
      end;

      if (ord(buff[cur]) > 30) and (ord(buff[cur]) < 127) then
      begin
        testStr := chr(buff[cur]);//Format('%c',[PChar(buff[cur])]);
        Write(testStr);
      end
      else
        Write('.');
    end;

    i := i + 16;
    Write(#13#10);
  Until flag = FALSE;

  Write(#13#10);

end;


function Add(a: Integer; b: Integer): Integer;
begin
  g_myName:='add';
  VBProtectBegin('Add_vpb');
  Result := a + b;
  VBProtectEnd();
  Writeln(g_myName);
end;


function sub(a: Integer; b: Integer): Integer;
begin
  g_myName:='sub';
  VBVirtualizeBegin('sub_vvb');
  Result := a - b;
  VBProtectEnd();
  Writeln(g_myName);
end;


function hello_delphi(): Integer;
var
 str:string;
 buf_input:PAnsiChar;
 buf_result:PAnsiChar;
 decrypteData      :PAnsiChar;
begin
  GetMem(decrypteData,TEST_ENCRYPT_DATA_SIZE);
  ZeroMemory(decrypteData,TEST_ENCRYPT_DATA_SIZE);
  Writeln('befor decryption: ');
  HEXDUMP(PByte(@g_test_x[1]),TEST_ENCRYPT_DATA_SIZE);
  VBProtectDecrypt(decrypteData,@g_test_x[1], TEST_ENCRYPT_DATA_SIZE);
  Writeln('after decryption: ');
  HEXDUMP(PByte(decrypteData),TEST_ENCRYPT_DATA_SIZE);

end;


begin
  try
      g_myName:='hello_delphi';
      Writeln(g_myName);
      Add(2,3);
      sub(3,2);
      hello_delphi();
    try
      Writeln(g_arr);
      g_myName:='hello_delphi1';
      Writeln(g_myName);
      g_arr := 20;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
  end;
  ExitCode:=0;
end.
