integrato ;)
Libreria per la redirezione dell'ouput di console su buffer
Dos2Win.c/Dos2Win.h

 
Dettagli:
 
Molte volte può essere necessario reindirizzare l'output di applicazioni dalla normale finestra console su un nostro buffer da trattare e stampare a schermo magari in una finestra (ad esempio per realizzare delle GUI per programmi a linea di comando).
Questa libreria permette appunto di fare ciò, reindirizzando l'ouput del processo aperto con CreateProcess() su una nostra pipe che andremo a leggere con ReadFile()

 
Codice:
 
  1. char * Dos2Win(char *process,char *param)
  2. {
  3. DWORD WaitReason;
  4. DWORD BytesRead;
  5. char *Buffer,*Cmd,temp[BUFSIZE];
  6.  
  7. HANDLE hReadPipe, hWritePipe;
  8. STARTUPINFO siStartupInfo;
  9. PROCESS_INFORMATION piProcessInfo;
  10. SECURITY_ATTRIBUTES sa; // Attibruti di sicurezza della pipe
  11.  
  12. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  13. sa.bInheritHandle = TRUE; // (¹)
  14. sa.lpSecurityDescriptor = NULL;
  15.  
  16. memset(&siStartupInfo, 0, sizeof(siStartupInfo));
  17. memset(&piProcessInfo, 0, sizeof(piProcessInfo));
  18.  
  19. // Creazione della pipe
  20. if (!CreatePipe (&hReadPipe, &hWritePipe, &sa, 0))
  21. {
  22. printf("Errore CreatePipe()\n");
  23. return NULL;
  24. }
  25.  
  26. // Alloco spazio per contenere la riposta
  27. Buffer = (char*)malloc((BUFSIZE + 1)*sizeof(char));
  28.  
  29. // Alloco spazio per 'eseguibile.exe + ' ' + 'parametri' + '\0'
  30. Cmd = (char*)malloc((strlen(process)+strlen(param)+2)*sizeof(char));
  31.  
  32. sprintf(Cmd,"%s %s",process,param);
  33.  
  34. siStartupInfo.cb = sizeof(siStartupInfo);
  35. siStartupInfo.dwFlags = STARTF_USESTDHANDLES // (²)
  36. | STARTF_USESHOWWINDOW;
  37. siStartupInfo.wShowWindow = SW_HIDE;
  38. // Redirigo lo standard input del processo sulla mia pipe
  39. siStartupInfo.hStdInput = hReadPipe;
  40. // Redirigo lo standard output del processo sulla mia pipe
  41. siStartupInfo.hStdOutput = hWritePipe;
  42. // Redirigo lo standard error del processo sulla mia pipe
  43. siStartupInfo.hStdError = hWritePipe;
  44.  
  45. // Apro il processo
  46. if (!CreateProcess(NULL,
  47. Cmd,
  48. &sa,
  49. &sa,
  50. TRUE, // (³)
  51. 0,
  52. NULL,
  53. NULL,
  54. &siStartupInfo,
  55. &piProcessInfo))
  56. {
  57. printf("Errore CreateProcess()\n");
  58. return NULL;
  59. }
  60.  
  61. // Attendo lesecuzione del comando
  62. WaitReason = WaitForSingleObject(piProcessInfo.hProcess,INFINITE);
  63.  
  64. // Pulisco il buffer
  65. memset(Buffer, 0, sizeof(Buffer));
  66. // Leggo la pipe
  67. do
  68. {
  69. BytesRead = 0;
  70. // Leggiamo "BUFSIZE" bytes dalla pipe
  71. ReadFile(hReadPipe, temp, BUFSIZE, &BytesRead, NULL);
  72. // Chiudo la stringa alla dimensione letta
  73.  
  74. temp[BytesRead] = '\0';
  75.  
  76. //Concateno
  77. strcat(Buffer,temp);
  78.  
  79. // Convertiamo i caratteri da DOS ad ANSI
  80. OemToAnsi(Buffer,Buffer);
  81. } while (BytesRead > BUFSIZE);
  82.  
  83. free(Cmd); // Rilascio il puntatore
  84.  
  85. // Chiudo la pipe
  86. CloseHandle(hReadPipe);
  87. CloseHandle(hWritePipe);
  88. // Chiuso il processo
  89. CloseHandle(piProcessInfo.hProcess);
  90. CloseHandle(piProcessInfo.hThread);
  91.  
  92. // Ritorno l'output letto e sistemato
  93. return Buffer;
  94. }
Nota (¹) (²) (³):
Ho segnato questi richiami in 3 punti importanti del codice:
  1. sa.bInheritHandle = TRUE; // (¹)
  1. siStartupInfo.dwFlags = STARTF_USESTDHANDLES
  2. | STARTF_USESHOWWINDOW; // (²)
  1. CreateProcess(...,
  2. ...
  3. ...,
  4. ...,
  5. TRUE, // (³)
Queste 3 impostazioni sono particolarmenti fondamentali per il corretto funzionamento del codice.
Come è riportato sulla documentazione ufficiale:

Struttura SECURITY_ATTRIBUTES

bInheritHandle: A Boolean value that specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.

Struttura STARTUPINFO

STARTF_USESTDHANDLES: The hStdInput, hStdOutput, and hStdError members are valid. If this flag is specified when calling one of the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE. For more information, see Handle Inheritance.

API CreateProcess()

bInheritHandles: If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.

Occorre permettere l'ereditarietà degli handle attraverso la pipe(¹), validare i membri hStdInput, hStdOutput, e hStdError della struttura STARTUPINFO(²) e impostare anche il paramentro bInheritHandles della CreateProcess()(³) per avere l'effettivo reindirizzamento dell'output sul nostro canale.

 
Esempio di utilizzo:
 
  1. #include <stdio.h>
  2. #include "Dos2Win.h"
  3.  
  4. int main()
  5. {
  6. char *out;
  7.  
  8. printf("Esecuzione comando \"dir\"\n");
  9. out = Dos2Win("cmd.exe","/c dir");
  10. printf("%s",out);
  11. free(out);
  12.  
  13. printf("Esecuzione comando \"nslookup\"\n");
  14. out = Dos2Win("nslookup.exe","www.suondmao.altervista.org");
  15. printf("%s",out);
  16. free(out);
  17.  
  18. return 0;
  19. }

 
Download:
 
Downloads: 262
Downloads: 250
Downloads: 149

 
Accorgimenti:
 
Si può utilizzare questo codice come base per realizzare un completo programma di gestione di altri processi, reindirizzando sia l'output (come fatto qui) che l'input del secondo processo su due pipe da comandare a piacimento. Questa tecnica veniva utilizzata spesso in passato per associare l'I/O del cmd.exe ad un socket creato per realizzare backdoors.

Script Execution Time: 0.160705 seconds - Visite: 645975
Copyright © 2007-2017 Suondmao v0.1.5-1