Ir al contenido


Foto

[TRUCO DELPHI] Detectar si mi Aplicacion esta corriendo desde el IDE de Delphi.


  • Por favor identifícate para responder
5 respuestas en este tema

#1 sir.dev.a.lot

sir.dev.a.lot

    Advanced Member

  • Miembros
  • PipPipPip
  • 545 mensajes
  • Location127.0.0.1

Escrito 01 diciembre 2016 - 07:50

[TRUCO DELPHI] Detectar si mi Aplicacion esta corriendo desde el IDE de Delphi.


delphi
  1. function DelphiLoaded : boolean;
  2.  
  3. function WindowExists(ClassName, WindowName: string): boolean;
  4. var
  5. PClassName, PWindowName: PChar;
  6. AClassName, AWindowName: array[0..63] of char;
  7. begin
  8. if ClassName = ''
  9. then PClassName := nil
  10. else PClassName := StrPCopy(@AClassName[0], ClassName);
  11. if WindowName = ''
  12. then PWindowName := nil
  13. else PWindowName := StrPCopy(@AWindowName[0], WindowName);
  14. if FindWindow(PClassName, PWindowName) <> 0
  15. then WindowExists := true
  16. else WindowExists := false;
  17. end; {WindowExists}
  18.  
  19. begin
  20. DelphiLoaded := false;
  21. if WindowExists('TPropertyInspector', 'Object Inspector') then
  22. if WindowExists('TMenuBuilder', 'Menu Designer') then
  23. if WindowExists('TApplication', 'Delphi') then
  24. if WindowExists('TAlignPalette','Align') then
  25. if WindowExists('TAppBuilder','') then
  26. DelphiLoaded := true;
  27. end;

Saludos!


  • 2

#2 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 01 diciembre 2016 - 03:47

Que tan segura es la funcion? No detecta la "mera" presencia de Delphi?

 

Es decir, si tengo Delphi abierto, y ejecuto mi aplicacion desde el exe, no devuelve True la funcion igualmente?

 

Yo lo hago de esta manera, aunque en realidad solo sirve si esta el depurador conectado:


delphi
  1. function RunFromDelphi: Boolean;
  2. begin
  3. Result := DebugHook <> 0;
  4. end;

DebugHook es una variable global de tipo Byte que es distinto a 0 si estamos depurando la aplicacion


Editado por Agustin Ortu, 01 diciembre 2016 - 03:48 .

  • 1

#3 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.965 mensajes
  • LocationMadrid - España

Escrito 01 diciembre 2016 - 06:51

Que tan segura es la funcion? No detecta la "mera" presencia de Delphi?
 
Es decir, si tengo Delphi abierto, y ejecuto mi aplicacion desde el exe, no devuelve True la funcion igualmente?
 
Yo lo hago de esta manera, aunque en realidad solo sirve si esta el depurador conectado:


delphi
  1. function RunFromDelphi: Boolean;
  2. begin
  3. Result := DebugHook <> 0;
  4. end;

DebugHook es una variable global de tipo Byte que es distinto a 0 si estamos depurando la aplicacion

 

 
El código mostrado por sir.dev.a.lot sólo detecta que existen "trazas del IDE de delphi" no detecta otra cosa.
 
Saber si una app se ejecuta desde el IDE e delphi es sencillo en WinXP buscando el padre de la app. A partir de Vista el tema no es tan sencillo pues existen formas de engañar al sistema para que interprete un padre falso de la app.
 
En este enlace cHackAll daba las bases para localizar el proceso padre, en este caso interesa el IDE de delphi y este es un ejemplo de conseguirlo:


delphi
  1. function GetOwnerProcessID (APID: DWord): DWord;
  2. var
  3. lSnapHandle: THandle;
  4. lProcStruct: PROCESSENTRY32;
  5. lPID: DWord;
  6. begin
  7. Result:= INVALID_HANDLE_VALUE;
  8. lSnapHandle:= CreateToolhelp32Snapshot (TH32CS_SNAPALL, 0);
  9. if (lSnapHandle <> INVALID_HANDLE_VALUE) and (APID <> INVALID_HANDLE_VALUE) then
  10. begin
  11. lProcStruct.dwSize:= SizeOf (PROCESSENTRY32);
  12. if Process32First (lSnapHandle, lProcStruct) then
  13. repeat
  14. lPID:= lProcStruct.th32ProcessID;
  15. if lPID = APID then
  16. begin
  17. Result:= lProcStruct.th32ParentProcessID;
  18. Break;
  19. end;
  20. until not Process32Next (lSnapHandle, lProcStruct);
  21. end;
  22. CloseHandle (lSnapHandle);
  23. end;
  24.  
  25. function GetParentProcess(PID : DWORD) : String;
  26. var
  27. SnapShot : THandle;
  28. ProcessEntry32 : TProcessEntry32;
  29. PPID : DWORD;
  30. PPHandle : THandle;
  31. PPPath : PAnsiChar;
  32. Size : Integer;
  33. IsWow64 : BOOL;
  34.  
  35. begin
  36. SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  37. if SnapShot <> INVALID_HANDLE_VALUE then
  38. begin
  39. GetMem(PPPath, MAX_PATH);
  40. Size := MAX_PATH;
  41. ProcessEntry32.dwSize := SizeOf(ProcessEntry32);
  42. if Process32First(SnapShot, ProcessEntry32) then
  43. repeat
  44. if ProcessEntry32.th32ProcessID = PID then
  45. begin
  46. PPID := ProcessEntry32.th32ParentProcessID;
  47. PPHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False,PPID);
  48. if PPHandle <> 0 then
  49. begin
  50. isWow64Process(GetCurrentProcess, @IsWow64);
  51. if IsWow64 then
  52. QueryFullProcessImageName(PPHandle, 0, PPPath, @Size)
  53. else
  54. GetModuleFileNameEx(PPHandle, 0, PPPath, Size);
  55. Result := PPPath;
  56. end
  57. else
  58. Result := EmptyStr;
  59. CloseHandle(PPHandle);
  60. Break;
  61. end;
  62. until not Process32Next(SnapShot, ProcessEntry32);
  63. CloseHandle(SnapShot);
  64. FreeMem(PPPath);
  65. end;
  66. end;
  67.  
  68.  
  69.  
  70. procedure TForm1.FormCreate(Sender: TObject);
  71. begin
  72. Label1.Caption:= GetParentProcess(GetCurrentProcessId);
  73. end;

 
Pero como no es oro todo lo que reluce, el siguiente código que publiqué en CD, permite engañar al sistema para que crea que el padre del proceso es otro:


delphi
  1. const
  2. SE_SECURITY_NAME = 'SeSecurityPrivilege';
  3. PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = $00020000;
  4. EXTENDED_STARTUPINFO_PRESENT = $00080000;
  5.  
  6. type
  7. PPROC_THREAD_ATTRIBUTE_LIST = Pointer;
  8.  
  9. STARTUPINFOEX = packed record
  10. StartupInfo: TStartupInfo;
  11. lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST;
  12. end;
  13. PSTARTUPINFOEX = ^STARTUPINFOEX;
  14.  
  15.  
  16. function InitializeProcThreadAttributeList(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST; dwAttributeCount, dwFlags: DWORD; var lpSize: Cardinal): Boolean; stdcall; external 'kernel32.dll';
  17. function UpdateProcThreadAttribute(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST; dwFlags, Attribute: DWORD; var pValue: DWORD; cbSize: Cardinal; pPreviousValue: Pointer; pReturnSize: PCardinal): BOOL; stdcall; external 'kernel32.dll';
  18. procedure DeleteProcThreadAttributeList(lpAttributeList: PPROC_THREAD_ATTRIBUTE_LIST); stdcall; external 'Kernel32.dll';
  19.  
  20.  
  21. function GetProcessId(FileName: String): DWORD;
  22. var
  23. proc: TProcessEntry32;
  24. hSysSnapshot: THandle;
  25. begin
  26. proc.dwSize := SizeOf(TProcessEntry32);
  27. hSysSnapshot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  28. if (hSysSnapshot <> INVALID_HANDLE_VALUE) and Process32First(hSysSnapshot, proc) then
  29. begin
  30. repeat
  31. if SameText(String(proc.szExeFile), FileName) then
  32. begin
  33. Result:= proc.th32ProcessID;
  34. break;
  35. end;
  36. until not (Process32Next(hSysSnapshot, proc));
  37. end;
  38. CloseHandle(hSysSnapshot);
  39. end;
  40.  
  41. function EnablePrivilege(name: String; Enable: boolean = true): boolean;
  42. var
  43. hToken: Cardinal;
  44. priv: TOKEN_PRIVILEGES;
  45. begin
  46. priv.PrivilegeCount:= 1;
  47. priv.Privileges[0].Attributes:= 0;
  48. if Enable then priv.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
  49. LookupPrivilegeValue(nil, PCHAR(name), priv.Privileges[0].Luid);
  50. OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
  51. AdjustTokenPrivileges (hToken, FALSE, priv, sizeof(priv), nil, PDWORD(nil)^);
  52. Result:= (GetLastError = ERROR_SUCCESS);
  53. CloseHandle (hToken);
  54. end;
  55.  
  56.  
  57. function CreateChildProcess(ExeName, ParentProcess: string): BOOL;
  58. var
  59. pi: TProcessInformation;
  60. si: STARTUPINFOEX;
  61. Size: Cardinal;
  62. hParent: Cardinal;
  63. begin
  64. Result:= false;
  65. EnablePrivilege(SE_SECURITY_NAME, True);
  66.  
  67. FillChar(si, SizeOf(si), 0);
  68. si.StartupInfo.cb := SizeOf(si);
  69. // si.StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  70. // si.StartupInfo.wShowWindow := SW_SHOWDEFAULT;
  71. FillChar(pi, SizeOf(pi), 0);
  72.  
  73. Size := 0;
  74. InitializeProcThreadAttributeList(nil, 1, 0, Size);
  75. si.lpAttributeList:= HeapAlloc(GetProcessHeap(), 0, Size);
  76. InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, Size);
  77. hParent := OpenProcess(PROCESS_ALL_ACCESS, False, GetProcessID(ParentProcess));
  78. UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, hParent, sizeof(hParent), nil, nil);
  79.  
  80. if CreateProcess(nil, PChar(ExeName), nil, nil, False, EXTENDED_STARTUPINFO_PRESENT, nil, nil, (PSTARTUPINFO(@si))^, pi) then
  81. begin
  82. Result:= true;
  83. CloseHandle(pi.hProcess);
  84. CloseHandle(pi.hThread);
  85. end;
  86.  
  87. DeleteProcThreadAttributeList(si.lpAttributeList);
  88. HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
  89. end;

La lectura de este tema: Como saber si la aplicación fue ejecutada desde Delphi, puede aportar algo de luz a este asunto y discutimos largamente sobre ello.
 
Subo un ejemplo de app que crea un proceso de esta forma y la natural. ¿notepad.exe es padre de notepad.exe? Pues si:

 

 post-12294-0-22294500-1480640173.jpg

 

De esta forma demuestro la dificultad de detectar que una app se ejecuta desde el IDE de delphi y la forma de engañar al IDE y al mismo Windows, :dmad:
 
 
Saludos.

Archivos adjuntos


  • 1

#4 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 01 diciembre 2016 - 08:06

Hecha la ley... :dlaug:


  • 0

#5 sir.dev.a.lot

sir.dev.a.lot

    Advanced Member

  • Miembros
  • PipPipPip
  • 545 mensajes
  • Location127.0.0.1

Escrito 02 diciembre 2016 - 06:51

Otra forma de identificar el Delphi, pero hay que hacer una lista de todos los Entornos liberados Version 1 a la 24, mas los distintos updates y etcetera, etcetera, etcetera.

 

Seria usar un MD5 y leer los nombres de los procesos y compararlos contra una lista que tenga todas las signatures / firmas del ejecutable...

 

Saludos!


  • 1

#6 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.965 mensajes
  • LocationMadrid - España

Escrito 02 diciembre 2016 - 12:58

Otra forma de identificar el Delphi, pero hay que hacer una lista de todos los Entornos liberados Version 1 a la 24, mas los distintos updates y etcetera, etcetera, etcetera.

 

Seria usar un MD5 y leer los nombres de los procesos y compararlos contra una lista que tenga todas las signatures / firmas del ejecutable...

 

Saludos!

 

Desde Windows Vista, es S.O. incorpora la posibilidad de cambiar el proceso padre por código, lo que hace inoperante tratar de identificar si un proceso corre o no desde el IDE de delphi. La única utilidad de esto es proteger un componente para evitar ser usado en una app sin licencia. Esa App puede incorporar un código similar al que mostré aquí haciendo inoperante cualquier intento de detectar si corre bajo el IDE de delphi. Eso sugiere que es mejor y mucho más cómodo dejar una "marca" en el componente siempre y eliminarla con la licencia.

 

 

Saludos.


  • 0