program copyover;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
Windows,
Winsock2;
const pipeName : pchar = '\\.\pipe\grendel';
type
Connection = class
socket : TSocket;
name : string;
end;
var
pipe : THandle;
a, w, len : cardinal;
prot : TWSAProtocol_Info;
g : array[0..1023] of char;
suc : boolean;
sock : TSocket;
hWSAData : TWSAData;
ver : integer;
c : Connection;
conns : TList;
SI: TStartupInfo;
PI: TProcessInformation;
f : file;
ret : integer;
begin
conns := TList.Create;
ver := WINSOCK_VERSION;
if (WSAStartup(ver, hWSAData) <> 0) then
exit;
pipe := INVALID_HANDLE_VALUE;
while (true) do
begin
pipe := CreateFile(pipeName, GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
if (pipe <> INVALID_HANDLE_VALUE) then
break;
ret := GetLastError();
if (ret <> ERROR_PIPE_BUSY) and (ret <> ERROR_FILE_NOT_FOUND) then
exit;
// All pipe instances are busy, so wait a second
if (ret = ERROR_PIPE_BUSY) then
if (not WaitNamedPipe(pipeName, 500)) then
exit;
end;
sock := -1;
repeat
suc := ReadFile(pipe, prot, sizeof(prot), w, nil);
if (not suc) or (w < sizeof(prot)) then
break;
if (suc) then
sock := WSASocket(prot.iAddressFamily, SOCK_STREAM, IPPROTO_IP, @prot, 0, 0);
suc := ReadFile(pipe, len, 4, w, nil);
if (not suc) or (w < 4) then
break;
suc := ReadFile(pipe, g, len, w, nil);
if (not suc) or (w < len) then
break;
if (suc) and (sock <> -1) then
begin
g[len] := #0;
c := Connection.Create;
c.socket := sock;
c.name := g;
conns.Add(c);
end;
until (not suc);
CloseHandle(pipe);
// give Grendel time to die
sleep(1000);
// check for any new grendel.exe in dir "bin\"
if (FileExists('bin\grendel.exe')) then
begin
if (CopyFile('bin\grendel.exe', 'grendel.exe', false)) then
begin
assign(f, 'bin\grendel.exe');
erase(f);
end;
end;
strpcopy(g, #13#10'In the void of space, you look around... fragments of memory flash by...'#13#10);
for w := 0 to conns.count - 1 do
begin
c := conns.items[w];
send(c.socket, g, strlen(g), 0);
end;
sleep(1000);
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);
SI.wShowWindow := sw_show;
if (not CreateProcess('grendel.exe', 'copyover', Nil, Nil, False, NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE, Nil, Nil, SI, PI)) then
exit;
pipe := CreateNamedPipe(pipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE or PIPE_READMODE_BYTE, 1, 0, 0, 10000, nil);
if (not ConnectNamedPipe(pipe, nil)) then
exit;
for a := 0 to conns.count - 1 do
begin
c := conns.items[a];
if (WSADuplicateSocket(c.socket, PI.dwProcessId, @prot) = -1) then
exit;
if (not WriteFile(pipe, prot, sizeof(prot), w, nil)) then
exit;
strpcopy(g, c.name);
len := strlen(g);
if (not WriteFile(pipe, len, 4, w, nil)) then
exit;
if (not WriteFile(pipe, g, len, w, nil)) then
exit;
closesocket(c.socket);
end;
CloseHandle(pipe);
WSACleanup;
end.