@@ -9,8 +9,6 @@ const builtin = @import("builtin");
99
1010const is_windows = builtin .os .tag == .windows ;
1111
12- const max_matches = 64 ;
13-
1412fn println (allocator : std.mem.Allocator , comptime fmt : []const u8 , args : anytype ) void {
1513 const msg = std .fmt .allocPrint (allocator , fmt , args ) catch return ;
1614 defer allocator .free (msg );
@@ -23,7 +21,11 @@ pub fn main(init: std.process.Init) u8 {
2321
2422 const args = init .minimal .args .toSlice (allocator ) catch return 1 ;
2523
26- if (args .len < 2 or std .mem .eql (u8 , args [1 ], "--help" ) or std .mem .eql (u8 , args [1 ], "-h" )) {
24+ const wants_help = for (args ) | a | {
25+ if (std .mem .eql (u8 , a , "--help" ) or std .mem .eql (u8 , a , "-h" )) break true ;
26+ } else false ;
27+
28+ if (args .len < 2 or wants_help ) {
2729 const usage =
2830 \\Usage: {s} <process-name|pid> [payload-path] [options]
2931 \\
@@ -36,7 +38,7 @@ pub fn main(init: std.process.Init) u8 {
3638 \\Options:
3739 \\ --type <name> Fully qualified type name (default: Hauyne.Payload.Entrypoint, Hauyne.Payload)
3840 \\ --method <name> Entry method name (default: Initialize)
39- \\ -h, --help Hello
41+ \\ -h, --help Show this help
4042 \\
4143 ;
4244 println (allocator , usage , .{args [0 ]});
@@ -65,6 +67,9 @@ pub fn main(init: std.process.Init) u8 {
6567 return 1 ;
6668 }
6769 method_name = args [i ];
70+ } else if (std .mem .startsWith (u8 , a , "--" )) {
71+ std .debug .print ("Unknown option: {s}\n " , .{a });
72+ return 1 ;
6873 } else if (payload_path == null ) {
6974 payload_path = a ;
7075 } else {
@@ -144,11 +149,9 @@ fn resolveTarget(io: std.Io, allocator: std.mem.Allocator, spec: []const u8) !u3
144149 return pid ;
145150 } else | _ | {}
146151
147- var matches : [max_matches ]u32 = undefined ;
148- var n : usize = 0 ;
149- try collectMatches (io , spec , & matches , & n , & inaccessible );
152+ const matches = try collectMatches (io , allocator , spec , & inaccessible );
150153
151- if (n == 0 ) {
154+ if (matches . len == 0 ) {
152155 if (inaccessible > 0 ) {
153156 std .debug .print ("No process matches '{s}' ({d} process(es) unreadable — try root or ptrace_scope=0)\n " , .{ spec , inaccessible });
154157 } else {
@@ -157,19 +160,17 @@ fn resolveTarget(io: std.Io, allocator: std.mem.Allocator, spec: []const u8) !u3
157160 return error .NotFound ;
158161 }
159162
160- // Compact .NET-valid PIDs over the front of `matches`. If vn == 0 no writes
161- // happen and matches[0..n] stays intact for the "none loaded hostfxr" list.
162163 var vn : usize = 0 ;
163- for (matches [0 .. n ] ) | pid | {
164+ for (matches ) | pid | {
164165 if (isDotNetProcess (io , allocator , pid , & inaccessible ) catch false ) {
165166 matches [vn ] = pid ;
166167 vn += 1 ;
167168 }
168169 }
169170
170171 if (vn == 0 ) {
171- std .debug .print ("'{s}' matched {d} process(es) but none loaded hostfxr: " , .{ spec , n });
172- printPidList (matches [0 .. n ] );
172+ std .debug .print ("'{s}' matched {d} process(es) but none loaded hostfxr: " , .{ spec , matches . len });
173+ printPidList (matches );
173174 return error .NoDotNetMatch ;
174175 }
175176 if (vn > 1 ) {
@@ -188,12 +189,13 @@ fn printPidList(pids: []const u32) void {
188189 std .debug .print ("\n " , .{});
189190}
190191
191- fn collectMatches (io : std.Io , name : [] const u8 , out : []u32 , count : * usize , inaccessible : * usize ) ! void {
192- if (is_windows ) return collectMatchesWindows (name , out , count );
193- return collectMatchesLinux (io , name , out , count , inaccessible );
192+ fn collectMatches (io : std.Io , allocator : std.mem.Allocator , name : []const u8 , inaccessible : * usize ) ! [] u32 {
193+ if (is_windows ) return collectMatchesWindows (allocator , name );
194+ return collectMatchesLinux (io , allocator , name , inaccessible );
194195}
195196
196- fn collectMatchesLinux (io : std.Io , name : []const u8 , out : []u32 , count : * usize , inaccessible : * usize ) ! void {
197+ fn collectMatchesLinux (io : std.Io , allocator : std.mem.Allocator , name : []const u8 , inaccessible : * usize ) ! []u32 {
198+ var matches : std .ArrayList (u32 ) = .empty ;
197199 const self_pid : u32 = @intCast (std .posix .system .getpid ());
198200
199201 var proc_dir = try std .Io .Dir .openDirAbsolute (io , "/proc" , .{ .iterate = true });
@@ -207,11 +209,10 @@ fn collectMatchesLinux(io: std.Io, name: []const u8, out: []u32, count: *usize,
207209 if (pid == self_pid ) continue ;
208210
209211 if (pidMatchesName (io , pid , name , inaccessible )) {
210- if (count .* >= out .len ) return ;
211- out [count .* ] = pid ;
212- count .* += 1 ;
212+ try matches .append (allocator , pid );
213213 }
214214 }
215+ return matches .items ;
215216}
216217
217218fn pidMatchesName (io : std.Io , pid : u32 , name : []const u8 , inaccessible : * usize ) bool {
@@ -257,7 +258,8 @@ fn nameMatches(candidate: []const u8, name: []const u8) bool {
257258 return false ;
258259}
259260
260- fn collectMatchesWindows (name : []const u8 , out : []u32 , count : * usize ) ! void {
261+ fn collectMatchesWindows (allocator : std.mem.Allocator , name : []const u8 ) ! []u32 {
262+ var matches : std .ArrayList (u32 ) = .empty ;
261263 const windows = std .os .windows ;
262264
263265 const TH32CS_SNAPPROCESS : windows.DWORD = 0x00000002 ;
@@ -301,7 +303,7 @@ fn collectMatchesWindows(name: []const u8, out: []u32, count: *usize) !void {
301303 .library_name = "kernel32" ,
302304 });
303305
304- if (Process32FirstW (snapshot , & entry ) == .FALSE ) return ;
306+ if (Process32FirstW (snapshot , & entry ) == .FALSE ) return matches . items ;
305307
306308 while (true ) {
307309 if (entry .th32ProcessID == self_pid ) {
@@ -320,13 +322,12 @@ fn collectMatchesWindows(name: []const u8, out: []u32, count: *usize) !void {
320322 exe_name ;
321323
322324 if (std .ascii .eqlIgnoreCase (stem , name ) or std .ascii .eqlIgnoreCase (exe_name , name )) {
323- if (count .* >= out .len ) return ;
324- out [count .* ] = entry .th32ProcessID ;
325- count .* += 1 ;
325+ try matches .append (allocator , entry .th32ProcessID );
326326 }
327327
328328 if (Process32NextW (snapshot , & entry ) == .FALSE ) break ;
329329 }
330+ return matches .items ;
330331}
331332
332333fn isDotNetProcess (io : std.Io , allocator : std.mem.Allocator , pid : u32 , inaccessible : * usize ) ! bool {
0 commit comments