Solved

Convert GUI app into console app for Win32 Env

Posted on 2016-10-03
5
138 Views
Last Modified: 2016-10-18
Hi all!,
 I was wondering if anyone out there would be willing and would be so kind to give me some pointers or to help me convert a GUI C++ program into a console (CMD.exe) style application that will run on a Windows XP box...

The program that i am looking or hoping to convert can be found at the following link :
 http://www.codeproject.com/Articles/577445/Querying-Wireless-Settings-and-Decrypting-Wireless

I have no idea what i am doing in C as i have only ever used Delphi 4, Delphi 6, VB3, VB6, PHP, Javascript and HTML (but as you would have gathered by that, i have a reasonable understanding of programming principles)

anyhow, i will leave it at that and i will be eagerly awaiting a reply from anyone :)
0
Comment
Question by:Jai Sewell
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
5 Comments
 
LVL 27

Accepted Solution

by:
Sinisa Vuk earned 500 total points
ID: 41827164
No need to convert ... because someone already make great source for this...
So... what I did is get wlan api from here (another great source for windows api is Jedi lib)
...add some changes ... and get this....
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, nduWlanAPI, Tlhelp32;

const
  WLAN_PROFILE_GET_PLAINTEXT_KEY = $00000004;
  CRYPT_STRING_HEX = $00000004;

const
  CRYPTPROTECT_LOCAL_MACHINE = 4;

type
  TLargeByteArray = array [0 .. Pred(MaxInt)] of byte;
  PLargeByteArray = ^TLargeByteArray;

  _CRYPTOAPI_BLOB = record
    cbData: DWORD;
    pbData: PByte;
  end;

  DATA_BLOB = _CRYPTOAPI_BLOB;
  PDATA_BLOB = ^DATA_BLOB;

type
  _CRYPTPROTECT_PROMPTSTRUCT = record
    cbSize: DWORD;
    dwPromptFlags: DWORD;
    hwndApp: HWND;
    szPrompt: PWideChar;
  end;

  CRYPTPROTECT_PROMPTSTRUCT = _CRYPTPROTECT_PROMPTSTRUCT;
  PCRYPTPROTECT_PROMPTSTRUCT = ^CRYPTPROTECT_PROMPTSTRUCT;

type
  TForm2 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

function CryptStringToBinaryA(pszString: LPCSTR; cchString: DWORD;
  dwFlags: DWORD; ppBinary: PBYTE; var ppcbBinary: DWORD;
  ppdwSkip: PDWORD; pdwFlags: PDWORD): BOOL; stdcall; external 'Crypt32.dll';

function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PLPWSTR;
  pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer;
  pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall; external 'Crypt32.dll';

implementation

{$R *.dfm}

function EnablePrivilege(name: String; Enable: boolean = true): boolean;
var
  hToken: THANDLE;
  priv: TOKEN_PRIVILEGES;
begin
  priv.PrivilegeCount:= 1;
  priv.Privileges[0].Attributes:= 0;
  if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
  LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
  AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
  Result:= (GetLastError = ERROR_SUCCESS);
  CloseHandle (hToken);
end;
 
function GetProcessId(FileName: String): DWORD;
var
   proc: TProcessEntry32;
   hSysSnapshot: THandle;
begin
   proc.dwSize := SizeOf(TProcessEntry32);
   hSysSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   if (hSysSnapshot <> INVALID_HANDLE_VALUE) and Process32First(hSysSnapshot, proc) then
   begin
     repeat
       if String(proc.szExeFile) = FileName then
       begin
         Result:= proc.th32ProcessID;
         break;
       end;
     until not (Process32Next(hSysSnapshot, proc));
   end;
   CloseHandle(hSysSnapshot);
end;

function ImpersonateToLoginUser: BOOL;
var
  hProcess, hToken: THANDLE ;
  ID: DWORD;
begin
  Result:= false;
  ID:= GetProcessID ('winlogon.exe');
  if ID > 0 then
  begin
    hProcess:= OpenProcess (MAXIMUM_ALLOWED, FALSE, ID);
    if hProcess <> INVALID_HANDLE_VALUE then
    begin
      Result:= OpenProcessToken(hProcess, MAXIMUM_ALLOWED, hToken);
      if Result then
      begin
        EnablePrivilege('SeDebugPrivilege');
        Result:= ImpersonateLoggedOnUser(hToken);
        CloseHandle(hToken);
      end;
      CloseHandle (hProcess);
    end;
  end;
end;

function ExtractKey(XMLText: String): String;
var
  ini, fin: integer;
begin
  Result:= '';
  ini:= Pos('<keyMaterial>', XMLText);
  fin:= Pos('</keyMaterial>', XMLText);
  if (ini <> -1) and (fin <> -1) then
  begin
    ini:= ini + Length('<keyMaterial>');
    Result:= Copy(XMLText, ini, fin-ini);
  end;
end;

function DecryptData(Key: String): String;
var
  Buffer: array [0..1023] of BYTE;
  Len: DWORD;
  DataIn, DataOut: DATA_BLOB;
  pbuf: PByte;
begin
  Result:= Key;
  Len:= 1024;
  ImpersonateToLoginUser;
  if CryptStringToBinaryA(PCHAR(Key), Length(Key), CRYPT_STRING_HEX, @Buffer[0], Len, 0, 0) then
  begin
    DataIn.cbData:= Len;
    DataIn.pbData:= @Buffer[0];
    DataOut.cbData:= 0;
    DataOut.pbData:= nil;
    if CryptUnprotectData (@DataIn, nil, nil, nil, nil, 0, @DataOut) then
      Result:= PCHAR(DataOut.pbData);
  end;
  RevertToSelf;
end;

function WifiGetPassWords: String;
var
  hClient: THandle;
  dwVersion: DWORD;
  pInterfaceInfoList: Pndu_WLAN_INTERFACE_INFO_LIST;
  pInterfaceGuid: PGUID;
  pProfileList: Pndu_WLAN_PROFILE_INFO_LIST;
  pstrProfileXml: PWCHAR;
  dwFlags: DWORD;
  dwGrantedAccess: DWORD;
  i,j: integer;
begin
  Result:= '';
  dwFlags:= 0;
  dwGrantedAccess:= 0;

  if ERROR_SUCCESS = WlanOpenHandle(1, nil, @dwVersion, @hClient) then
  begin
    if ERROR_SUCCESS = WlanEnumInterfaces(hClient, nil, @pInterfaceInfoList) then
    begin
      for i:= 0 to pInterfaceInfoList^.dwNumberOfItems - 1 do
      begin
        pInterfaceGuid:= @pInterfaceInfoList^.InterfaceInfo[pInterfaceInfoList^.dwIndex].InterfaceGuid;
        if ERROR_SUCCESS = WlanGetProfileList(hClient, pInterfaceGuid, nil, @pProfileList) then
        begin
          for j:=0 to pProfileList.dwNumberOfItems-1 do
          begin
            dwFlags:= WLAN_PROFILE_GET_PLAINTEXT_KEY;
            if ERROR_SUCCESS = WlanGetProfile(hClient,	pInterfaceGuid, pProfileList.ProfileInfo[j].strProfileName, nil, @pstrProfileXml, @dwFlags, @dwGrantedAccess) then
            begin
              Result:= Result + String(pProfileList.ProfileInfo[j].strProfileName) + ': '+ DecryptData(ExtractKey(String(pstrProfileXml))) + #13 + #10;
              WlanFreeMemory(pstrProfileXml);
            end;
          end;
        end;
        WlanFreeMemory(pProfileList);
      end;
      WlanFreeMemory(pInterfaceInfoList);
    end;
    WlanCloseHandle(hClient, nil);
  end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  Edit1.Text := WifiGetPassWords;
end;

Open in new window


... hope you'll need this for a good cause....
1
 

Author Comment

by:Jai Sewell
ID: 41827456
That works quite well but is not quite there yet...

I would like to decrypt the hex code in the windows xp registry that stores the saved wifi password, however this cannot be decrypted to a clear text ascii value, i know for certain that it can be converted to a 64 part hexadecimal value (just like NirSoft's WirelessKeyView does), i will paste up a whole heap of stuff i have gathered together in an attempt to demonstrate what i mean...

the follow hex is converted to the 64 part hex :
C8 02 00 00 03 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 74 65 73 6C 61 73 6F 75 72 63 65 73 2E 63 6F 6D 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 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 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 0
0 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 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 82 65 B9 D7 BE 1C D2 01 03 00 00 80 00 00 00 00 01 00 00 00 D0 8C 9D DF 01 15 D1 11 8C 7A 00 C0 4F C2 97 EB 01 00 00 00 7A 4F 87 A7 63 9A 26 4F AC C0 B7 DE 77 A5 22 66 00 00 00 00 02 00 00 00 00 00 03 66 00 00 A8 00 00 00 10 00 00 00 38 63 D1 60 FC 12 BD 00 DD 30 CD 0D 4D 3A 39 7A 00 00 00 00 04 80 00 00 A0 00 00 00 10 00 00 00 9F 9D F0 DB 34 EC B8 6F 8E BE 9E 82 A5 DC 1E 29 28 00 00 00 73 1C C6 88 7B 81 A1 2D 08 34 FA 6F B6 19 2B BD FF AF 44 E2 69 9D B8 A4 24 FE 7E 9D 8A 87 64 AB 71 59 74 A5 DA 28 2B C4 14 00 00 00 86 B6 8F D4 06 CA C4 B9 B5 83 84 78 55 F6 7D E0 A6 25 11 41

and the 64 part hex looks like :
fbf59171ee510db622f1a335a0dc86328b24cd7b12f705e4cb2cf72a0d496dfd

and the windows xp registry key is :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WZCSVC\Parameters\Interfaces\{32F9DEC7-9EC8-4972-A7D9-28C9624DD331}
0
 

Author Closing Comment

by:Jai Sewell
ID: 41848895
Just run you're code again after i had the epiphany whilst laying in bed trying to get to sleep... to run the code with administrator privilege and it works bloody perfect!...
I must thank you Sinisa!.
And for anyone looking to use this code, it surely does work!, i used it in Delphi Enterprise 6 (6.163) on Windows 7 Ultimate 64bit... oooh and please also note that you will need an active wireless adapter, if you dont, then you simply wont get the codes (fully decrypted to i might add!, which far exceeded what i thought i would be able to accomplish, but please note that in WinXP it is impossible to fully decrypt the hex values from the registry to the original clear text password but you will get a 64 part hex value that you can use as the password instead, like WORD!, enter this 64 part hex value as the wifi password and you will be granted authorization and access!).

To start a Delphi app with escalated privilege by default (run as admin, simply by executing the app!, without changing "Compatibility settings/options" or right-clicking and selecting "Run as Administrator" ), please use the following code from stackoverflow post http://stackoverflow.com/questions/14703013/adding-manifest-for-admin-rights-request.

Create the following files uac.manifest, uac.rc, uac_xp.manifest and uac_xp.rc
Enter the code below for each file starting with uac.manifest, then uac.rc etc...

-uac.manifest

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="MyApp" type="win32"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

-uac.rc

1 25 "uac.manifest"

-uac_xp.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" processorArchitecture="x86"/>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <!-- Windows Vista application security requirements. -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!--Windows 7-->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
      <!--Windows Vista-->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
    </application>
  </compatibility>  
</assembly>

-uac_xp.rc

1 24 "uac_xp.manifest"


Now add the desired rc file (uac.rc or uac_xp.rc) to your project via the "Project > Add to project" menu item. This will create the {$R} directive in your project file:

program Project1;

{.$R 'uac.res' 'uac.rc'} // UAC only
// OR
{$R 'uac_xp.res' 'uac_xp.rc'} // UAC + XP Themes

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
0
 

Author Comment

by:Jai Sewell
ID: 41848968
But this code does not work with WinXP as i had originally asked!, please note that people, if you try you get an error that says wlanapi.dll could not be found!
0

Featured Post

Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi Spellcheck in Webbrowser 1 77
Please explain "Multi-Tenant Services" 5 123
PHP preg_replace code convert to Delphi 14 98
Shared files and folders migration 2 67
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question