Visualizzazione post con etichetta programmazione. Mostra tutti i post
Visualizzazione post con etichetta programmazione. Mostra tutti i post

lunedì 23 settembre 2019

PowerShell: Creare una GUI per uno script PowerShell

Gli script PowerShell vengono generalmente creati ed eseguiti all'interno di un'interfaccia a riga di comando e anche i risultati vengono visualizzati all'interno della finestra CLI (Command Line Interface). Ciò ne scoraggia l'utilizzo da parte degli utenti comuni. Tuttavia, PowerShell è un potente strumento di automazione e consente l'utilizzo di una varietà di oggetti .NET Framework. Per creare una semplice interfaccia grafica per gli script PowerShell basta utilizzare l'API .NET.

In quest'articolo verrà mostrato come creare un semplice Form. Prima di iniziare assicurarsi che la versione di PowerShell installata sul proprio sistema sia 3.0 o superiore. Per farlo basta eseguire $PSVersionTable.PSVersion da una finestra PowerShell per visualizzare un'output come quello mostrato in FIG 1. Se la variabile non esiste allora probabilmente si tratta della versione 1.0

Versioni di PowerShell:
  • Versione 1.0: distribuita nel 2006 come download opzionale. Obsoleta
  • Versione 2.0: distribuita nel 2009 come parte di Windows 7/Windows Server 2008. L'unica versione che supporta Windows XP e Windows Server 2003.
  • Versione 3.0: distribuita nel 2012 come parte di Windows 8/Windows Server 2012. Sono state completate le caratteristiche principali del linguaggio ed è stato riprogettato l'editor ISE.
  • Versione 4.0: distribuita nel 2013 come parte di Windows 8.1/Windows Server 2012R2. Aggiunto DSC (Desired State Configuration).
  • Versione 5.0: distribuita nel 2016 come parte di Windows 10. In tale versione sono state introdotte numerose funzionalità ed estensioni.
  • Versione 5.1: distribuita nel 2017 come parte di Windows 10 Anniversary Update\Windows Server 2016.

PowerShell, visualizzare la versione installata nel sistema
FIG 1 - PowerShell, visualizzare la versione installata nel sistema
Il blocco di codice per creare un semplice Form è il seguente:

Add-Type -assembly System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Text ='La mia finestra in PowerShell'
$form.Width = 400
$form.Height = 200
$form.AutoSize = $true
$form.ShowDialog()

Per la creazione del Form viene utilizzata la classe System.Windows.Forms di .NET. Per caricare tale classe all'interno dello script PowerShell si utilizza tale codice:
Add-Type -assembly System.Windows.Forms

Nell'istruzione successiva 
$form = New-Object System.Windows.Forms.Form
viene avviata una nuova istanza della classe System.Windows.Forms.Form di .NET Framework che genera una finestra vuota (Form o modulo) in cui è possibile iniziare ad aggiungere controlli.

Successivamente viene impostato un titolo per la finestra attraverso la proprietà Text, quindi vengono impostate le dimensioni (larghezza e altezza) tramite le proprietà Width e Height
$form.Text ='La mia finestra in PowerShell'
$form.Width = 400
$form.Height = 200

Per fare in modo che il Form si ridimensioni automaticamente in base al suo contenuto viene utilizzata la proprietà AutoSize.
$form.AutoSize = $true

L'ultima istruzione 
$form.ShowDialog()
non fa altro che richiamare il metodo ShowDialog per visualizzare a video il Form.

Per creare lo script basta copiare il blocco di codice sopra indicato all'interno di un editor di testo (come ad es. Blocco Note) e salvare il file con estensione .ps1 (ad es. Form1.ps1). Per eseguirlo da PowerShell digitare il nome del file .ps1 comprensivo del percorso (ad es. c:\Users\glubrano\desktop\Form1.ps1). Il risultato sarà quello mostrato in FIG 2.

Dal seguente link è possibile scaricare il file contenente il blocco di codice.
DOWNLOAD Form1.ps1
Form in PowerShell
FIG 2 - Form in PowerShell



Il Form così creato serve a ben poco. Possiamo aggiungere altri elementi come un etichette (label), una casella combinata (combobox) e un pulsante (button). Quello che andremo a costruire nelle prossime righe è uno script PowerShell che permette di selezionare, all'interno della combobox, una specifica cartella e, cliccando sul pulsante, visualizzarne la data dell'ultima modifica.

Iniziamo ad inserire un etichetta. Per farlo basta aggiungere il seguente blocco di codice prima dell'ultima istruzione $form.ShowDialog().

$Label1 = New-Object System.Windows.Forms.Label
$Label1.Text = "Directory:"
$Label1.Location  = New-Object System.Drawing.Point(5,10)
$Label1.AutoSize = $true
$form.Controls.Add($Label1)

Con la prima istruzione viene creata una nuova istanza della classe System.Windows.Forms.Label che genera l'etichetta. Successivamente viene specificato il testo che l'etichetta andrà a visualizzare quindi, tramite System.Drawing.Point(5,10) andiamo a specificare la posizione, all'interno del Form, in cui verrà visualizzata l'etichetta. Anche in questo caso viene impostata la proprietà AutoSize in modo che le dimensioni dell'elemento si adeguano in base al contenuto. 
L'ultima istruzione 
$form.Controls.Add($Label1)
aggiunge l'etichetta al form precedentemente creato.


Il passo successivo consiste nell'inserire una casella combinata accanto all'etichetta. Aggiungiamo il seguente blocco di codice al nostro file .PS1 (assicurandoci che l'ultima istruzione sia sempre $form.ShowDialog()) .

$ComboBox1 = New-Object System.Windows.Forms.ComboBox
$ComboBox1.Width = 150
$Folders = get-childitem -dir | Select Name
Foreach ($Folder in $Folders){
 $ComboBox1.Items.Add($Folder.Name);
}
$ComboBox1.Location  = New-Object System.Drawing.Point(60,10)
$form.Controls.Add($ComboBox1)

In questo blocco gran parte delle istruzioni sono analoghe a quanto visto per i blocchi precedenti. Con l'istruzione
$Folders = get-childitem -dir | Select Name
andiamo ad assegnare alla variabile $Folders l'elenco delle directory presenti nel path da cui stiamo richiamando lo script. Il ciclo ForEach non fa altro che estrarre il nome delle directory e inserirle all'interno della combobox.


Il blocco successivo provvede ad inserire all'interno del Form due etichette: Label2 e Label3. Quest'ultima mostrerà la data dell'ultima modifica della cartella selezionata quando si clicca sul pulsante presente alla destra della combobox.

$Label2 = New-Object System.Windows.Forms.Label
$Label2.Text = "Data modifica:"
$Label2.Location  = New-Object System.Drawing.Point(5,40)
$Label2.AutoSize = $true
$form.Controls.Add($Label2)

$Label3 = New-Object System.Windows.Forms.Label
$Label3.Text = ""
$Label3.Location  = New-Object System.Drawing.Point(90,40)
$Label3.AutoSize = $true
$form.Controls.Add($Label3)

Blocco codice relativo al pulsante. 

$Button1 = New-Object System.Windows.Forms.Button
$Button1.Location = New-Object System.Drawing.Point(220,10)
$Button1.Size = New-Object System.Drawing.Size(150,20)
$Button1.Text = "Visualizza data modifica"
$form.Controls.Add($Button1)

Anche questi 2 blocchi vanno inseriti prima dell'istruzione $form.ShowDialog(). Nel blocco relativo al pulsante troviamo l'istruzione 
$Button1.Size = New-Object System.Drawing.Size(120,20)
che consente di specificare la dimensione dell'elemento.

Adesso non resta che inserire un'ultimo blocco in cui andiamo ad aggiungere un evento relativo al click sul pulsante. 

$Button1.Add_Click(
 {
  $Label3.Text =  (get-item  $ComboBox1.selectedItem).LastWriteTime 
 }
)

L'istruzione
$Label3.Text =  (get-item  $ComboBox1.selectedItem).LastWriteTime 
rileva la data di modifica della directory selezionata all'interno della combobox e la visualizza attraverso la Label3.

L'intero script può essere scaricato dal seguente link
DOWNLOAD Form2.ps1

Eseguendo lo script, l'output sarà simile a quello mostrato in FIG 3.
PowerShell, Visualizzare la data di modifica di una data cartella attraverso il Form
FIG 3 - PowerShell, Visualizzare la data di modifica di una data cartella attraverso il Form


In modo analogo possono essere inseriti ulteriori elementi all'interno del Form come:
- CheckBox
- ChekedListBox
- ContextMenu
- DateTimePicker
- GroupBox
- HScrollBar
- ListBox
- ListView
- Menu
- PictureBox
- ProgressBar
- RadioButton
- TabControl
- TextBox
- TrackBar
- TreeView
- VScrollBar


Per creare in maniera semplice Form accattivanti per script in PowerShell, è possibile usare l'editor online https://poshgui.com/Editor. Tale editor, attraverso una semplice interfaccia grafica, consente di progettare/realizzare una GUI per i propri script PowerShell anche a chi è poco pratico e scaricare il codice sorgente.
POSHGUI, Editor online GUI PowerShell
FIG 4 - POSHGUI, Editor online GUI PowerShell





domenica 7 maggio 2017

C#: Elencare i file PST connessi ad Outlook

Per poter utilizzare Outlook è necessario disporre di un account di posta (Microsoft Exchange, POP o IMAP). L'account di posta è composto da un'oggetto di tipo Store che viene utilizzato per memorizzare i dati. Lo Store, a sua volta, è composto da cartelle e Item (come e-mail, contatti, appuntamenti, ecc). Anche un file archivio (file PST) è composto da un'oggetto di tipo Store. Per chiarire il concetto, si veda la seguente figura.


Outlook Store
FIG 1 - Outlook Store


In questo articolo verrà mostrato come, utilizzando C#, è possibile ottenere l'elenco dei file PST connessi ad Outlook.
Per poter interagire con gli oggetti di Outlook è necessario utilizzare, all'interno della nostra applicazione, il namespace Microsoft.Office.Interop.Outlook.

Una volta aggiunti i riferimenti a Microsoft.Office.Interop.Outlook, la prima operazione da effettuare è quella di creare un oggetto Outlook Application.
Outlook.Application olApp = new Outlook.Application();

Tale oggetto può essere utilizzato per diversi scopi, noi lo useremo per accedere agli altri oggetti di Outlook sottostanti.

Il nostro obiettivo è quello di accedere agli Store. Tale operazione è possibile attraverso l'oggetto NameSpace che contiene la sessione di collegamento ad Outlook
Outlook.NameSpace olNs=olApp.Session;
Outlook.Stores olStores=olNs.Stores;

A questo punto in olStores abbiamo tutti gli Store del profilo Outlook. Attraverso un ciclo For andiamo ad analizzare ciascun Store e verificare se si tratta di un file di dati (olStore.IsDataFileStore) e se la sua estensione è .PST (olStore.FilePath.ToString().ToUpper().EndsWith(".PST"). In caso affermativo il nome del file, comprensivo di path, verrà accodato ad una variabile stringa (pstList) che, al termine, conterrà l'elenco di tutti i file PST connessi ad Outlook
for (int i = 1; i <= olStores.Count; i++){
 olStore=olStores[i];
 if(olStore.IsDataFileStore){ //se si tratta di un file di dati
  if ((olStore.FilePath.ToString().ToUpper().EndsWith(".PST")) ){
   count++;
   pstList += String.Format("{0}. {1}{2}",count,olStore.FilePath,Environment.NewLine);
  }
    
 }
 if (olStore !=null)
  Marshal.ReleaseComObject(olStore);

 }

Alla fine non resta che chiudere le sessioni e rilasciare gli oggetti.
if (olStores !=null)
 Marshal.ReleaseComObject(olStores);
if (olStore !=null)
 Marshal.ReleaseComObject(olStore);
if (olApp !=null)
 Marshal.ReleaseComObject(olApp);
if (olNs != null)
 Marshal.ReleaseComObject(olNs);

Per chi vuole può scaricare il codice sorgente dell'esempio dal seguente link.
DOWNLOAD



lunedì 16 gennaio 2017

C#: Oscurare il monitor utilizzando le API di Windows

In questo articolo verrà mostrato come gestire il monitor e oscurarlo tramite l'utilizzo di C# e le API (Application Programming Interface) di Windows. Per la gestione del monitor tramite C# è possibile utilizzare la funzione PostMessage(). Tale funzione invia il messaggio specificato alla coda associata al thread che ha generato la finestra, quindi esce senza aspettare che il messaggio venga processato.

La prima operazione da eseguire consiste nel dichiarare la funzione PostMessage() all'interno del codice. In Visual C# questo avviene con le seguenti righe di codice
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

I parametri di PostMessage() sono:
hWnd - rappresenta l'Handle della finestra che riceve il messaggio;
Msg - specifica il messaggio da inviare alla finestra;
wParam - permette di specificare informazioni aggiuntive relative al messaggio;
lParam - specifica lo stato del monitor.


hWnd - Handle della finestra

Per quanto riguarda l'handle da passare alla funzione ci sono diverse possibilità. Nel caso di applicazioni basate su finestre è possibile utilizzare l'handle della finestra corrente: this.Handle.
All'interno di librerie dll o di applicazioni console, invece, è possibile utilizzare delle costanti come indicato su MSDN: 0xFFFF  per inviare il messaggio a tutte le finestre superiori oppure -1 per inviare il messaggio alla finestra superiore a tutte le altre. 

In alternativa si può ricercare l'handle di una finestra aperta utilizzando la seguente funzione
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
La funzione recupera l'handler della finestra superiore al form la cui classe è indicata da lpClassName e nella barra del titolo è presente la stringa lpWindowName. Passando null ad entrambi i parametri della funzione verrà recuperato l'handle della finestra superiore a tutte le altre.



Msg - Messaggio da inviare alla finestra

Dopo l'handler è necessario specificare il messaggio da inviare alla finestra. Per il messaggio è possibile utilizzare la costante 0x0112 che indica un comando di sistema. Il valore, all'interno del codice allegato all'articolo, è rappresentato dalla seguente costante:
const int WM_SYSCOMMAND = 0x0112;



wParam - Informazioni aggiuntive relative al messaggio

Al parametro wParam viene passato il valore 0xF170 che permette la gestione dell'alimentazione del monitor. All'interno del codice tale parametro viene passato utilizzando la costante SC_MONITORPOWER.


lParam - Stato del monitor

L'ultimo parametro da specificare è lParam che indica lo stato in cui impostare il monitor: -1 per accesso, 2 per spento, 1 per standby. 


C#, Oscurare lo schermo tramite PostMessage()
FIG 1 - C#, Oscurare lo schermo tramite PostMessage()


Di seguito è possibile scaricare i file sorgenti del progetto. Il progetto può essere aperto e modificato tramite Visual Studio oppure tramite ambienti di sviluppo di terze parti come ad es. SharpDevelop
DOWNLOAD
Turn Off Screen
FIG 2 - Turn Off Screen



Al posto di PostMessage() è possibile utilizzare anche altri funzioni API come SendMessage(), PostThreadMessage(), SendNotifyMessage() e SendMessageCallback().

SendMessage()
Invia il messaggio ad una o più finestre e attende che venga processato.
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

  
PostThreadMessage()
Inserisce il messaggio all'interno della coda del thread specificato. Anche in questo caso la funzione termina senza attendere che il thread processi il messaggio.
[DllImport("user32.dll")]
static extern bool PostThreadMessage(uint idThread, uint Msg, UIntPtr wParam, IntPtr lParam);

 
SendNotifyMessage()
Invia il messaggio ad una o più finestre. Se la finestra è stata creata dal thread chiamato, SendNotifyMessage chiama la routine della specifica finestra e non termina finchè il messaggio non è stato processato. Se la finestra è stata creata da un thread diverso, SendNotifyMessage passa il messaggio alla routine delle finestre e termina senza attendere l'esecuzione del messaggio.
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern bool SendMessageCallback(IntPtr hWnd, uint Msg,UIntPtr wParam, IntPtr lParam, SendMessageDelegate lpCallBack,
                                       UIntPtr dwData);

  
SendMessageCallback()
Richiama la routine della finestra specificata e termina immediatamente. Dopo che la routine ha processato il messaggio, il sistema chiama la funzione di callback specificata passandole il risultato dell'elaborazione.    
[DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern bool SendNotifyMessage(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam);

  

lunedì 20 aprile 2015

C# : Verificare la versione di Outlook installata

In questo articolo mostrerò come individuare la versione di Microsoft Outlook installata, sulla propria postazione o su una workstation remota, utilizzando C#
L'operazione può essere effettuata in modi diversi e l'applicazione che ho creato è molto semplice e offre ampi margini di miglioramento. Quello che andrò a fare è semplicemente verificare la versione del file Outlook.exe
OutlookVer
FIG 1 - OutlookVer

Come primo passo chiedo all'utente se intende verificare la versione di Outlook installata sulla workstation locale o su una workstation remota. Nel caso di postazione remota verifico se la postazione è raggiungibile.
Il passo successivo consiste nell'individuare il path (percorso) del file Outlook.exe. Per conoscere il path di installazione di outlook vado ad interrogare il valore stringa Path presente nella seguente chiave di registro
HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\OUTLOOK.EXE

Per la workstation locale utilizzo l'istruzione 
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,RegistryView.Registry32).OpenSubKey(RegKey);
mentre per verificare una postazione remota utilizzo l'istruzione
RegistryKey.OpenRemoteBaseKey(RegistryHive.CurrentUser, textBoxWKSName.Text).OpenSubKey(RegKey);

Una volta individuato il path del file Outlook.exe, verifico la sua versione tramite l'istruzione 
FileVersionInfo.GetVersionInfo(_path)

A questo punto non resta che visualizzare a video un messaggio con la versione di Outlook installata
Versione di Outlook
FIG 2 - Versione di Outlook
Di seguito è possibile scaricare i file sorgenti del progetto. Il progetto può essere aperto e modificato tramite Visual Studio oppure tramite ambienti di sviluppo di terze parti come ad es. SharpDevelop
DOWNLOAD


lunedì 3 novembre 2014

VBS: Recuperare il product key di Windows tramite VBS


Esistono diversi tool di terze parti che permettono il recupero del product key del sistema operativo e di altre applicazioni, tra questi segnalo l'ottimo ProduKey della NirSoft (www.nirsoft.net) scaricabile gratuitamente ed eseguibile senza alcuna installazione.
In questo articolo verrà mostrato come recuperare il product key di Windows tramite uno script VBS.
Il Product Key di Windows è una sequenza di 25 caratteri (lettere e numeri) divisi in 5 gruppi da 5 caratteri ognuno. I caratteri utilizzati all'interno di un product key sono BCDFGHJKMPQRTVWXY2346789 mentre non vengono utilizzati i caratteri AEILNOSUZ015. Il product key è memorizzato all'interno del registro di sistema e codificato in un valore DWORD all'interno della chiave HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId.
Nella decodifica del valore DWORD DigitalProductId bisogna fare attenzione alla versione di Windows infatti, a partire da Windows 8, il metodo di codifica del product key è cambiato.

Lo script che ho creato visualizza le informazioni relative al nome del prodotto, il Product ID e il Product Key permettendo, inoltre, di salvare le informazioni trovate all'interno di un file di testo (.txt).
Di seguito il sorgente dello script VBS


Option Explicit 

Dim strComputer, objWMIService, objItem, Caption, colItems
Dim ProductName,ProductID,ProductKey,ProductInfo, Version, Win8Version, WinOlderVersion
Win8Version = "6.2 6.3"
WinOlderVersion ="6.1 6.0 5.2 5.1 5.0"

'Di seguito i valori della stringa CurrentVersion presente all'interno della chiave HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion che indica la versione di Windows
'Windows 8.1                 6.3
'Windows Server 2012 R2      6.3
'Windows 8                   6.2
'Windows Server 2012         6.2
'Windows 7                   6.1
'Windows Server 2008 R2      6.1
'Windows Server 2008         6.0
'Windows Vista               6.0
'Windows Server 2003 R2      5.2
'Windows Server 2003         5.2
'Windows XP 64-Bit Edition   5.2
'Windows XP                  5.1
'Windows 2000                5.0
'Crea oggetto wscript.shell
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
' in Caption memorizzo la Versione di Windows
For Each objItem in colItems
    Caption = objItem.Caption  
Next
 Dim objshell,path,DigitalID, Result 
 Set objshell = CreateObject("WScript.Shell")
 'Recupero le informazioni dalle chiavi di registro"
 DigitalID = objshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId")
 ProductName = "Product Name: " & objshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName")
 ProductID = "Product ID: " & objshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID")
 Version= objshell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
 
 If InStr(Win8Version,Version) Then
  'Windows 8 o Windows 8.1
  ProductKey = "Product Key: " & GetKeyWindows8(DigitalID) 
 Else
  If InStr(WinOlderVersion,Version) Then
     ' Windows 7 o antecedente
  ProductKey = "Product Key: " & GetKeyWindows7(DigitalID) 
  Else
     msgBox "Versione di Windows non supportata." & vblf &"Il presente Script è stato testato per versioni di Windows comprese tra Windows 2000 e Windows 8.1" , vbOKOnly+vbCritical, "Versione Windows non supportata"
  ProductKey ="Product Key: Non Rilevato"
     End If   
  
 End If
 
 ProductInfo = ProductName  & vbNewLine & ProductID  & vbNewLine & ProductKey
 'Mostra i dati e chiedi se si intende salvare in un file
 If vbYes = MsgBox(ProductInfo  & vblf & vblf & "Vuoi salvare le informazioni in un file?", vbYesNo + vbQuestion, "Windows Product Key") then
    Save ProductInfo
 End If


'Convert i valori binari della chiave "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId" in caratteri per Windows 8
Function GetKeyWindows8(Key)
    Const KeyOffset = 52
    Dim isWin8, Maps, i, j, Current, KeyOutput, Last, keypart1, insert
    'Check if OS is Windows 8
    isWin8 = (Key(66) \ 6) And 1
    Key(66) = (Key(66) And &HF7) Or ((isWin8 And 2) * 4)
    i = 24
    Maps = "BCDFGHJKMPQRTVWXY2346789"
    Do
        Current= 0
        j = 14
        Do
           Current = Current* 256
           Current = Key(j + KeyOffset) + Current
           Key(j + KeyOffset) = (Current \ 24)
           Current=Current Mod 24
            j = j -1
        Loop While j >= 0
        i = i -1
        KeyOutput = Mid(Maps,Current+ 1, 1) & KeyOutput
        Last = Current
    Loop While i >= 0 
    keypart1 = Mid(KeyOutput, 2, Last)
    insert = "N"
    KeyOutput = Replace(KeyOutput, keypart1, keypart1 & insert, 2, 1, 0)
    If Last = 0 Then KeyOutput = insert & KeyOutput
    GetKeyWindows8 = Mid(KeyOutput, 1, 5) & "-" & Mid(KeyOutput, 6, 5) & "-" & Mid(KeyOutput, 11, 5) & "-" & Mid(KeyOutput, 16, 5) & "-" & Mid(KeyOutput, 21, 5)
 
End Function
'Converte i valori binari della chiave "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId" in caratteri per Windows 7
Function GetKeyWindows7(ProductID)
    Const KeyOffset = 52
 Dim i, Cur, x, Maps
    i = 0
    Maps = "BCDFGHJKMPQRTVWXY2346789"
    Do
        Cur = 0
        x = 14
  i=i+1
        Do
            Cur = Cur * 256
            Cur = ProductID(x + KeyOffset) + Cur
            ProductID(x + KeyOffset) = (Cur \ 24) And 255
            Cur = Cur Mod 24
            x = x -1
        Loop While x >= 0
  if (i Mod 6) = 0 Then
   ProductKey = "-" & ProductKey
   i = i + 1
  End If  
  ProductKey = Mid(Maps, Cur + 1, 1) & ProductKey   
    Loop While i < 29
    GetKeyWindows7 = ProductKey
End Function

'Salva i dati in un file
Function Save(Data)
    Dim fso, fName, txt,objshell,UserName
    Set objshell = CreateObject("wscript.shell")
    'Crea un file di testo con nome WindowsKeyInfo.txt, nello stesso percorso del vbs, contenente le informazioni
    fName = "WindowsKeyInfo.txt"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set txt = fso.CreateTextFile(fName)
    txt.Writeline Data
    txt.Close
End Function

Per chi volesse scaricare il file VBS può utilizzare il link di seguito
DOWNLOAD

mercoledì 8 ottobre 2014

Powershell: creare musica con Powershell

Tramite Powershell possiamo far emettere un beep dall'altoparlante della workstation tramite l'istruzione
[console]::beep()

Al metodo possiamo passare anche la frequenza e la durata del beep in modo da modificarne il suono
[console]::beep(int frequenza, int durata)

ad es:
[console]::beep(784,150) 

Il metodo può essere utile, ad esempio, per richiamare l'attenzione di un operatore durante l'esecuzione di uno script Powershell ma di seguito illustrerò un utilizzo più goliardico.

Modificando la frequenza e la durata del beep e servendoci di altre istruzioni come cicli, pause, variabili ecc., è possibile creare anche musichette carine come la seguente "Marcia Imperiale" di Star Wars
[console]::beep(440,500)       
[console]::beep(440,500) 
[console]::beep(440,500)        
[console]::beep(349,350)        
[console]::beep(523,150)        
[console]::beep(440,500)        
[console]::beep(349,350)        
[console]::beep(523,150)        
[console]::beep(440,1000) 
[console]::beep(659,500)        
[console]::beep(659,500)        
[console]::beep(659,500)        
[console]::beep(698,350)        
[console]::beep(523,150)        
[console]::beep(415,500)        
[console]::beep(349,350)        
[console]::beep(523,150)        
[console]::beep(440,1000)

Oppure questa famosa sequenza



[console]::beep(900,400) 
[console]::beep(1000,400) 
[console]::beep(800,400) 
[console]::beep(400,400) 
[console]::beep(600,1600)

Di seguito è possibile scaricare un file .ZIP contenenti vari script Powershell (file con estensione .PS1) con diversi esempi di musichette realizzate tramite il metodo sopra indicato. Nel file Leggimi.txt ho indicato da quali siti ho copiato le istruzioni contenute nei file .PS1 (purtroppo non ho né tempo né conoscenze di musica per poterli realizzare in autonomia)
DOWNLOAD

sabato 4 ottobre 2014

VBS: Sintesi vocale con SAPI.SpVoice

Se vogliamo far parlare il nostro PC tramite Visual Basic Script (VBS) e utilizzando la sintesi vocale inclusa in Windows possiamo utilizzare il seguente codice:


StrText=("Please allow me to introduce myself") 
StrText2=("I'm a man, of wealth, and taste") 
set ObjVoice = CreateObject("SAPI.SpVoice") 
ObjVoice.Volume = 100
ObjVoice.Speak StrText 
ObjVoice.Speak StrText2 

Lo script utilizza il metodo SAPI.SpVoice per la sintesi vocale delle stringhe di testo passate. Di seguito è possibile scaricare il file VBS:
DOWNLOAD


Sintesi Vocale
FIG 1 - Sintesi Vocale
Di default la voce della sintesi vocale fornita in Windows è in inglese ma è possibile scaricare, anche gratuitamente, diverse voci e lingue. Lo script utilizza la voce selezionata all'interno del Sistema Operativo.

lunedì 9 giugno 2014

Visualizzare funzioni di una DLL tramite DLL Export Viewer

Chi programma sa bene che a volte è necessario conoscere le funzioni messe a disposizione di una DLL esterna. Proprio in questi casi DLL Export Viewer può fare al caso nostro. Oltre a visualizzare le funzioni e il loro indirizzo di memoria virtuale contenute all’interno di un file DLL permette anche di visualizzare le funzioni e le DLL richiamate da un processo in esecuzione sulla macchina. Tali informazioni ci possono essere d’aiuto anche in ambito di debug di un’applicazione: ad es. una volta verificato l’indirizzo della funzione che ci interessa possiamo inserire un breakpoint all’interno del nostro debugger.

Il tool può essere scaricato da www.nirsoft.net/utils/dll_export_viewer.html, non richiede installazione e l’utilizzo è molto semplice. L’ultima versione al momento disponibile è la 1.63. Una volta avviato il file eseguibile ci verrà presentata una finestra in cui dovremmo selezionare l’operazione di nostro interesse:


Schermata iniziale DLL Export Viewer
Fig. 1 Schermata iniziale
Load all functions from standard system DLLs (user32, Kernel32, and so on…)
Ci permette di visualizzare tutte le funzioni presenti nelle DLL di sistema

Load functions from the following DLL file: (You can specify wildcard too)
Permette di specificare una DLL da analizzare

Load functions from the DLL files specified in the following text file: (CRLF delimited file)
Permette di indicare un file di testo contenente l’elenco delle DLL da analizzare

Load functions from all DLLs attached to the selected process:
Elenca le funzioni e le DLL richiamate da un particolare processo.

Una volta selezionata l’opzione desiderata ed eventualmente indicata la DLL da analizzare possiamo cliccare su OK per procedere con la visualizzazione dell’elenco delle funzioni. 

Fig. 2 Analisi DLL


L’applicazione ci permette di salvare il report in formato HTML, di ricercare con google informazioni su una particolare funzione e di copiare nella clipboard il suo indirizzo.


Insomma DLL Export Viewer rappresenta un piccolo tool che potrà essere molto utile ai programmatori e sistemisti.

venerdì 6 giugno 2014

Keylogger in Ajax

In questo articolo illustrerò come costruire un semplice keylogger per una pagina web sfruttando Ajax.
Prima di iniziare ci tengo a specificare che il presente articolo è solo a scopo informativo e, ricordo, che rubare dati e password è un reato perseguibile penalmente.

Con l’avvento di nuove tecniche di programmazione introdotte dal Web 2.0 abbiamo assistito ad una maggiore iterazione tra gli utenti e le pagine web grazie anche allo scambio di informazioni tra client e server che avviene in maniera più o meno trasparente. Questa evoluzione porta con se nuovi tipi di problemi relativi alla sicurezza.

Di seguito mostrerò come costruire un keylogger su una pagina web. In pratica il keylogger cattura tutto quello che l’utente scrive nella pagina web. Di per sé questo tipo di programma non sembra essere molto pericoloso ma cosa succederebbe se sfruttassimo un sito vulnerabile a XSS? Potremmo fare in modo che il nostro script venga caricato e catturi ciò che digita l’utente sulla pagina del sito vulnerabile.

Per prima cosa creiamo un file HTML con dei campi in cui l’utente andrà a scrivere. Ho chiamato questo file home.html. Ciò che ci interessa è che la nostra pagina, con l’utilizzo di chiamate asincrone, invii dati al server ogni volta che l’utente digiti qualche tasto. Per fare questo ci aiuteremo con javascript e utilizzeremo l’oggetto XMLHttpRequest.  Per intercettare la pressione di un tasto da parte dell’utente, nella pagina HTML  ho usato l’evento onkeypress all’interno del tag  <body> e richiamo l’handler keylog() che andrò a sviluppare all’interno del file keylogger.js.

<body onkeypress="keylog()">

Il ruolo della funzione keylog() presente in keylogger.js è quello di intercettare il tasto premuto e far partire una richiesta GET al server. Event.charCode ci fornisce il valore Unicode del tasto premuto. Nel caso in cui event.charCode non fosse supportato dal browser, andremo a leggere il valore del tasto premuto utilizzando la proprietà event.keycode. Ad es. Internet Explorer supporta solo la proprietà event.keycode. La funzione fromCharCode ci permette di ricavare una stringa dai valori Unicode rilevati:

keyPressed = String.fromCharCode(evt.charCode ?evt.charCode : evt.keyCode);

Una volta individuato il tasto premuto keylog() richiama la funzione makeRequest() che ci permette di effettuare una chiamata GET asincrona verso il server.

makeRequest('log.php?keyPressed=' + keyPressed);

Come è possibile notare, con la funzione makeRequest andiamo a richiamare il file log.php a cui passiamo il tasto premuto. 

Il file log.php è costituito da poche righe di codice; per semplicità sono stati omessi volutamente i controlli e la gestione degli errori. Il suo scopo è quello di ricevere il valore del tasto premuto attraverso GET e salvarlo all’interno di un file di log sul server (file.log). Ovviamente affinché log.php riesca a scrivere il file è necessario fornire gli opportuni permessi sulla cartella.

Qui potete scaricare i sorgenti dei file creati

Conclusioni
Creare un keylogger in una pagina web è un’operazione piuttosto semplice e, in questo caso, volutamente innocua, infatti il nostro keylogger intercetterà solo ciò che viene digitato sulla nostra pagina web. Tuttavia qualche malintenzionato potrebbe creare un'apposita pagina di phishing oppure sfruttare qualche sito vulnerabile a XSS per rubare i dati degli utenti che accedono al sito. Avere un buon antivirus spesso non basta ma bisogna usare buonsenso e prestare la massima attenzione. La forza di una catena si misura dalla forza del suo anello più debole e, nel campo della sicurezza informatica, l'anello più debole è spesso rappresentato dall'essere umano.