Solved

Convert GUI app into console app for Win32 Env

Posted on 2016-10-03
5
146 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

Ready to get started with anonymous questions?

It's easy! Check out this step-by-step guide for asking an anonymous question on Experts Exchange.

Question has a verified solution.

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

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
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…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses
Course of the Month10 days, 10 hours left to enroll

631 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