There is a really strange situation in my Ruby-based processes: their /proc/self/environ is really broken. For some reason, the ENV inside Ruby looks fine but I'd like to understand what's going on.
Processes are started using bundle exec, for example bundle exec sidekiq. The end result is that the /proc/<pid>/environ file only contains a couple of bytes (usually 4) of the invoked command plus a bunch of zeroes. In the example above, the environ file would look like
$ sudo hexdump -C /proc/2613895/environ
00000000 65 6b 69 71 00 00 00 00 00 00 00 00 00 00 00 00 |ekiq............|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000390 00 00 00 00 00 00 00 |.......|
00000397
When invoking another command line, for example a rake task, the environ file would contain the last couple of characters of the rake task name.
Since the environ file cannot be modified by the process itself after it starts, it must have been set by whomever made the execve call but I am stupefied who might be responsible and why.
This seems to mostly happen when processes are started through systemd, but none of the other processes started by systemd show the same behaviour; only the ones started through bundle exec so I'm thinking that it's not related to systemd.
The /proc/$pid/environ file normally only contains the environment passed to the process when it was created. It does not reflect any changes to its environment the process may have made after it began execution. Furthermore, it simply exposes the portion of the stack of the process which contained the original env vars. If the process modifies those stack locations that will be reflected in the content of that procfs file. See, for example, https://unix.stackexchange.com/questions/302948/change-proc-pid-environ-after-process-start.
I would complain to the Ruby team since they shouldn't be stomping on the original env var stack locations.
Related
Newb-question here. I have searched a couple days for the solution but dont't get anywhere. Using windbg preview.
There's a process that loads a dll and I want to see the disassembly of the addresses that are called from inside the dll. No symbols available because it is third party. I can find the entry point and break on it but after that I cannot step into the dll. I know I need to load the dll into windbg but I can't put it in the arguments when I start the exe because I only know the entry point after the module is loaded.
If I use .load on my dll and set a breakpoint on entry it doesn't work either.
Anyone done this before and can tell me what I need to do to step into the dll's assembly?
edit:
In windbg I launched the executable (.exe) and want to see the addresses and operations inside a .dll that are called during a specific operation in the program.
Simple things first: .load is for loading WinDbg Plugins into the WinDbg process. That's not what you want.
I'm assuming that you want to do more a reverse engineering than debugging. WinDbg is not ideal for this task. There are certainly better tools like IDA.
Analyzing without executing
But anyway, let's get into it. I'll choose an arbitrary DLL for this example. It is a DLL provided with the AMD display driver, C:\AMD\PSP Driver\WTx64\amdtee_api32.dll and I have no clue about it.
Open WinDbg Preview
Go to "Open dump file" (this is not really intuitive, but it will work)
In the file open dialog, enter *, so DLLs will be displayed (by default it's limited to DMP files)
Choose the DLL to be loaded
At this point, it will say
Microsoft (R) Windows Debugger Version 10.0.21349.1004 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [C:\AMD\PSP Driver\WTx64\amdtee_api32.dll]
You can now operate on the DLL with the same commands as during a live debugging session.
0:000> lm
start end module name
10000000 10055000 amdtee_api32 (export symbols) amdtee_api32.dll
So I have no PDB file available, just export symbols, as there are:
0:000> x *!*
7ffe0300 SharedUserData!SystemCallStub = <no type information>
10001050 amdtee_api32!TEEC_InitializeContext (<no parameter info>)
[...]
And we can disassemble a function:
0:000> uf amdtee_api32!TEEC_InitializeContext
amdtee_api32!TEEC_InitializeContext:
10001050 55 push ebp
10001051 8bec mov ebp,esp
10001053 83ec08 sub esp,8
10001056 c745f801000000 mov dword ptr [ebp-8],1
1000105d 837d0c00 cmp dword ptr [ebp+0Ch],0
10001061 750a jne amdtee_api32!TEEC_InitializeContext+0x1d (1000106d) Branch
[...]
You can even access the memory where the DLL is loaded to
0:000> db amdtee_api32
10000000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
10000010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........#.......
10000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
10000030 00 00 00 00 00 00 00 00-00 00 00 00 10 01 00 00 ................
10000040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
10000050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
10000060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS
10000070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
Im able to install application with NSIS installer and later I update TaskManager->Startup preferences to disabled. After I uninstall and reinstall the application, Startup preferences defaults to previous user preference of "disabled". I want the installer to enforce Enabled always after new install, so application startups on reboot. How to achieve this with NSIS coding.
Thanks
I believe Microsoft wants this to be a purely user-controlled setting, but in any case the method Task Manager uses is to modify the appropriate REG_BINARY value in the following registry locations in either HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE, as appropriate:
SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run
SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run32
SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\StartupFolder
Enabled items contain the data:
02 00 00 00 00 00 00 00 00 00 00 00
or
06 00 00 00 00 00 00 00 00 00 00 00
Disabled items contain data starting with 03000000... or 07000000... and followed by some hex values [perhaps it's a timestamp?], e.g.:
03 00 00 00 F4 0B 28 C9 9D 79 D1 01
I'm unclear what the distinction is between the ones that start with 02 and 06, but it seems 02s become 03s and 06s becomes 07s when disabled.
To ensure your startup item is enabled, either use WriteRegBin to set it back to 020000000000000000000000 or 060000000000000000000000, or just use DeleteRegValue and delete the value entirely.
I'm trying to teach myself assembly, and am using LLDB to debug. So far, so good, but I'm wondering whether there's a quick way to inspect the memory at an address stored in a register?
Of course, I can do
register read rbp
(for example), and then use the address via
memory read <address> ...
but really I'd like to use the register name directly in the arguments to the 'memory' command (possibly with an offset). That seems like a natural thing to want to do, but so far I haven't been able to find anything about this.
You can use
(lldb) x $eax
0x799be060: f0 e6 1c 01 04 00 00 00 88 23 04 00 98 23 04 00 .........#...#..
0x799be070: a8 23 04 00 b8 23 04 00 00 00 00 00 00 00 00 00 .#...#..........
To see the memory contents displayed as e.g. 4 floats, use
(lldb) x/4f $eax
0x799be060: 0.0000000000000000000000000000000000000288183643
0x799be064: 0.00000000000000000000000000000000000000000000560519386
0x799be068: 0.000000000000000000000000000000000000000380088195
0x799be06c: 0.000000000000000000000000000000000000000380110616
I am using dtruss on MacOS X 10.8.5 in an attempt to see the conversation between a running application and an SSL server it talks to. Unlike strace on Linux, I'm not seeing full strings of data in the output, like I would expect to find as the program does send and recv on the file descriptor.
How can I get dtruss to show me the data which the app is sending and receiving with the SSL server?
Before anyone tells me to proxy the connections to an SSL server I control, yes I know this trick, and no this particular app is too smart to fall for it.
dtruss is both an elegant example of a script written for DTrace and a demonstration of what DTrace can accomplish. However, although its similarity to truss or strace is deeply welcome on the relatively barren OS X, I suspect that dtruss was never intended to be a complete substitute for either.
In any case, your question is a bit ambiguous: I'm not sure whether you are concerned that the strings that you see are truncated or that you don't see any strings at all for sendto() or recvfrom() (the underlying interfaces revealed by DTrace). I'll address both.
Firstly, DTrace collects data in the kernel; user-land buffers are obtained with the D language's copyin() or copyinstr() before being recorded and transmitted back to the consumer --- typically the dtrace(1) command. DTrace requires that its kernel buffer size be known at compile-time and therefore imposes a limit on the otherwise unpredictable length of a string. This limit is 256 bytes by default; if you are seeing truncation then you could change the limit by adding, e.g.,
#pragma D option strsize=512
below dtruss's existing pragma.
Secondly, dtruss is hard-coded to know about the formatting requirements of a variety of system calls. You don't see any buffer interpretation for sendto() or recvfrom() in its output because they're not handled explicitly in the source. There's nothing to stop you finding somewhere suitable to add them but you could instead write your own script:
bash-3.2# cat sr.d
#pragma D option rawbytes
syscall::sendto:entry,
syscall::recvfrom:entry
/pid == $target/
{
self->bufp = arg1;
self->size = arg2;
}
syscall::sendto:return,
syscall::recvfrom:return
/pid == $target && self->bufp && self->size/
{
printf("%s():\n", probefunc);
tracemem(copyin(self->bufp, self->size), 64);
printf("\n");
self->bufp = self->size = NULL;
}
bash-3.2# dtrace -qs ./sr.d -p 16988
sendto():
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 hello...........
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
^C
bash-3.2#
Note that, as for strings, we're obliged to provide a hard limit on tracemem()'s use of DTrace's data-recording buffer. If the limit is rarely approached then this has the irritating result that the output can be overwhelming and mostly redundant. If you know that you're looking for strings then you could simply use copyinstr() instead; if you have a more modern DTrace implementation than my OS X 10.6.8 then you may find that you can write
tracemem(copyin(self->bufp, self->size), 64, self->size);
where the second argument is still a hard limit on the number of bytes recorded but the number of bytes displayed is limited by the optional third argument.
Finally, note that the user-land address is recorded on entry to the system call but used only on exit. This is a common idiom that allows the system call to fault-in the data if necessary --- DTrace won't do so itself and will produce an error at run-time if asked to trace a non-resident address.
Using Windows Server 2003 in a multi-user environment (via Remote Desktop, using it as an application server), how to mount a (preferably encrypted) volume in a way, that won't show up on any other user's desktop?
Tried, and failed approaches:
tweaking user rights -display of mounted volume can not be changed.
Bestcrypt / truecrypt. Both of them displays the volume for a local administrator
You're going to be hard-pressed to find a solution for your exact problem. Drive mount points aren't stored on the user level (afaik). There are a couple of workarounds that you can use that aren't guaranteed to be secure:
hide access to certain drive letters based on group policy. Not very secure, easy to workaround.
Don't mount a seperate volume: use NTFS encryption and simply set security permissions on certain folders.
Is there any particualr reason it has to be an entire drive? If you're trying to avoid allowing the local-admin having rights to a local drive, you're pretty much out of luck unless you use a third-party-probably-going-to-fail-horribly solution. You can jury-rig something with Group Policy to disallow local admin access, but it's going to be hard and error prone.
If your desired goal is to have separate folders (or volumes) that other users cannot access, store the files on a remote server. That way local administrators on the application server cannot arbitrarily access other peoples folders. (Unless they have Domain Admin or Enterprise Admin rights) You can set up a single big network drive and have different user folders on it, each encrypted using NTFS/other solution and only have read/write rights for that single user.
There's a key in the Registry that's used to hide mapped drives.
If you want to stop any combination of drives appearing in My Computer
Add the Binary Value of 'NoDrives' in the registry at
"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
Here is the table of all the values (Note that you can add up values to hide multiple drives, also the value is binary type but must be entered in hexadecimal, so if you add up a few drives, get ready for a little hex math. ) :
A 1 00 00 00
B 2 00 00 00
C 4 00 00 00
D 8 00 00 00
E 16 00 00 00
F 32 00 00 00
G 64 00 00 00
H 128 00 00 00
I 00 1 00 00
J 00 2 00 00
K 00 4 00 00
L 00 8 00 00
M 00 16 00 00
N 00 32 00 00
O 00 64 00 00
P 00 128 00 00
Q 00 00 1 00
R 00 00 2 00
S 00 00 4 00
T 00 00 8 00
U 00 00 16 00
V 00 00 32 00
W 00 00 64 00
X 00 00 128 00
Y 00 00 00 1
Z 00 00 00 2
Even if the drive letters are hidden - the volumes are still accessible unless you change ACLs on the filesystem itself - why is this so unpalatable?
NTFS supports mounting volumes inside directories.
Example - instead of mounting an external drive as D:, you can mount it under C:\mountedVolumes\externalHardDrive
You can then use ACL's on the parent folder (mountedVolumes) to prevent users other than yourself from accessing it. If they can't get into the folder, they can't get into the drive, or see that it's there. It just looks like a folder they can't open.
Note: This assumes that you have administrative rights (at least for when you first set this up), and that other people don't (so they can't just take ownership of mountedVolumes and go into the drive anyway)