I'm sick of carrying my Lenovo laptop. So, I picked up my thumb drive and populated it with stuff that seemed good to carry around. MASM32, OllyDBG, Sysinternals Suite. Now I've become a sort of inverted village bicycle, the computers throughout the library all ride me. I'm not fond of being ridden, (by electronics, anyway). I've decided to start putting my beginners level assembly language knowledge to work. So, I suppose this is a plan.
I want my thumb drive to contain a program, or group of programs/batch files/scripts, to enhance my windows environment whenever I insert my thumbdrive and initialize autorun. There is, however, one obstacle. It's name is automount. Automount, as many of you know, automatically assigns driveletters to disks. How do I get the drive letter of a disk mounted by automount?
Another obstacle is deep freeze. It would be nice to know which computers could be trusted to hold onto my environment data. The luxury, however, cannot exist in this library due to the nature of the users. Spyware and Malware would run rampant if it wasn't for Deep Freeze. For those of you unfamiliar with Deep Freeze, the software has a default settings template which is applies to each computer on startup. No computer will leave that state unless the Deep Freeze template is modified. Now, I know %path% can be set through cmd.exe, but Deep Freeze, or Windows itself, does not allow changes to persist after session termination. So, is there a way to modify environment variables and load them into the current session without logging out of windows?
I want my thumb drive to contain a program, or group of programs/batch files/scripts, to enhance my windows environment whenever I insert my thumbdrive and initialize autorun. There is, however, one obstacle. It's name is automount. Automount, as many of you know, automatically assigns driveletters to disks. How do I get the drive letter of a disk mounted by automount?
Another obstacle is deep freeze. It would be nice to know which computers could be trusted to hold onto my environment data. The luxury, however, cannot exist in this library due to the nature of the users. Spyware and Malware would run rampant if it wasn't for Deep Freeze. For those of you unfamiliar with Deep Freeze, the software has a default settings template which is applies to each computer on startup. No computer will leave that state unless the Deep Freeze template is modified. Now, I know %path% can be set through cmd.exe, but Deep Freeze, or Windows itself, does not allow changes to persist after session termination. So, is there a way to modify environment variables and load them into the current session without logging out of windows?
I did some research on MSDN and found a few functions which can access the registry through ADVAPI32.lib.
I also found the following in the MASM32 forums
http://www.masm32.com/board/index.php?topic=2061.msg16395
I also viewed the Key HKLM:\SYSTEM\MountedDevices and found that the information about all mounted devices is stored in this key. The keys store their information in either \??\Volume{GUID} of type REG_BINARY with hex data which provides information about the device vendor, its device type (USB, IDE etc), vendor id and the GUID. The other type is similar save the naming convention which is \DosDevice\B:, where B: is a drive letter. The Type and data is the same granted you're looking at the same device.
The little bit about USB I do know reminds me that Vendor ID's do not change per system, GUID's I believe do. So my first inclination is to search these keys' data streams for a vendor id that matches that of my flash drive.
How does one search strings using ASM? Does one make liberal use of the cmp instruction then jmp? Does anyone have an algorithm already handy they're willing to share?
RegOpenKeyEx
LONG WINAPI RegOpenKeyEx(
__in HKEY hKey,
__in_opt LPCTSTR lpSubKey,
__reserved DWORD ulOptions,
__in REGSAM samDesired,
__out PHKEY phkResult
);
LONG WINAPI RegOpenKeyEx(
__in HKEY hKey,
__in_opt LPCTSTR lpSubKey,
__reserved DWORD ulOptions,
__in REGSAM samDesired,
__out PHKEY phkResult
);
I also found the following in the MASM32 forums
http://www.masm32.com/board/index.php?topic=2061.msg16395
I also viewed the Key HKLM:\SYSTEM\MountedDevices and found that the information about all mounted devices is stored in this key. The keys store their information in either \??\Volume{GUID} of type REG_BINARY with hex data which provides information about the device vendor, its device type (USB, IDE etc), vendor id and the GUID. The other type is similar save the naming convention which is \DosDevice\B:, where B: is a drive letter. The Type and data is the same granted you're looking at the same device.
The little bit about USB I do know reminds me that Vendor ID's do not change per system, GUID's I believe do. So my first inclination is to search these keys' data streams for a vendor id that matches that of my flash drive.
How does one search strings using ASM? Does one make liberal use of the cmp instruction then jmp? Does anyone have an algorithm already handy they're willing to share?
Okay, I may have found a better method for getting my disk that does NOT involve the registry. It also seems much simplier to implement. It turns our that transversing the registry was a bit of a headache!
I found FindFirstVolume:http://msdn.microsoft.com/en-us/library/aa364425(VS.85).aspx and FindNextvolumehttp://msdn.microsoft.com/en-us/library/aa364431(VS.85).aspx. These two functions seem to work hand in hand and provide a simple interface! I'll post some ASM once developed.
Thanks for reading!
I found FindFirstVolume:http://msdn.microsoft.com/en-us/library/aa364425(VS.85).aspx and FindNextvolumehttp://msdn.microsoft.com/en-us/library/aa364431(VS.85).aspx. These two functions seem to work hand in hand and provide a simple interface! I'll post some ASM once developed.
Thanks for reading!
An even simpler solution: I assume you're coding the AutoRun tool yourself? Simply make it look at it's exe-path on startup: GetModuleFileName(0, buffer, countof(buffer));. From there, it's pretty easy to grab the drive letter :)
You can change the PATH and other environment settings on a running system (assuming your user account isn't a LUA - if so, you can only change the per-user environment strings, which should be good enough for PATH anyway). Thing is it won't affect already-running programs, only ones started after the change.
If you set environment variables in your autorun tool, you can have those variables propagate to any child processes the autorun spawns (like, a menu bar or whatever).
You can change the PATH and other environment settings on a running system (assuming your user account isn't a LUA - if so, you can only change the per-user environment strings, which should be good enough for PATH anyway). Thing is it won't affect already-running programs, only ones started after the change.
If you set environment variables in your autorun tool, you can have those variables propagate to any child processes the autorun spawns (like, a menu bar or whatever).
Is it possible to set the %PATH% to include paths from a different drive letter? I was thinking of trying to create a junction on the filesystem to make it appear to be a path on the %systemdrive%
Also, I wanted to test GetModuleFileName and produced the following
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
.data?
FilePath LPSTR ?
FilePathLength DWORD ?
.code
start:
invoke GetModuleFileName, NULL, addr FilePath, addr FilePathLength
invoke MessageBox, NULL, addr FilePath, addr FilePathLength, MB_OK
invoke ExitProcess, NULL
end start
The messagebox title is asm32\asm\environment\main.exe
Where is the rest of the path?
It appears the data types are different. Is there a way to return different data types or change data types?
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
.data?
FilePath LPSTR ?
FilePathLength DWORD ?
.code
start:
invoke GetModuleFileName, NULL, addr FilePath, addr FilePathLength
invoke MessageBox, NULL, addr FilePath, addr FilePathLength, MB_OK
invoke ExitProcess, NULL
end start
The messagebox title is asm32\asm\environment\main.exe
Where is the rest of the path?
It appears the data types are different. Is there a way to return different data types or change data types?
You want GetModulePath ;)
Don't be too worried about data types defined by C.
They use a dozen names to define the same primitives.
Don't be too worried about data types defined by C.
They use a dozen names to define the same primitives.
invoke GetModuleFileName, NULL, addr FilePath, addr FilePathLength
something looks wrong there..
DWORD GetModuleFileName(
HMODULE hModule, // handle to module to find filename for
LPTSTR lpFilename, // pointer to buffer for module path
DWORD nSize // size of buffer, in characters
);
you haven't specified the size... or even the buffer
FilePath LPSTR ?
FilePathLength DWORD ?
should be
FilePath db (MAX_PATH+1) dup (?)
then..
invoke GetModuleFileName, NULL, addr FilePath, (sizeof FilePath) -1
should get you the desired results.. windows FILLS the buffer you supply, it does NOT return a pointer to some string in memory with the filename...
simple mistake, and i suspect the partial path you saw was simply a dirty buffer.. next time you should check the return code from GetModuleFileName
Return Values
If the function succeeds, the return value is the length, in characters, of the string copied to the buffer.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
something looks wrong there..
DWORD GetModuleFileName(
HMODULE hModule, // handle to module to find filename for
LPTSTR lpFilename, // pointer to buffer for module path
DWORD nSize // size of buffer, in characters
);
you haven't specified the size... or even the buffer
FilePath LPSTR ?
FilePathLength DWORD ?
should be
FilePath db (MAX_PATH+1) dup (?)
then..
invoke GetModuleFileName, NULL, addr FilePath, (sizeof FilePath) -1
should get you the desired results.. windows FILLS the buffer you supply, it does NOT return a pointer to some string in memory with the filename...
simple mistake, and i suspect the partial path you saw was simply a dirty buffer.. next time you should check the return code from GetModuleFileName
Return Values
If the function succeeds, the return value is the length, in characters, of the string copied to the buffer.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
Is it possible to set the %PATH% to include paths from a different drive letter?
Sure thing - all the items in PATH are normally fully qualified (drive letter and all).I was thinking of trying to create a junction on the filesystem to make it appear to be a path on the %systemdrive%
No reason to do this :) - you'd have to much around with creating junctions on the target machine and removing them again while you're done, slightly messy.The messagebox title is asm32\asm\environment\main.exe
Where is the rest of the path?
Hmm, you don't get a fully-qualified name?Where is the rest of the path?
Your code is wrong, anyway - I'm a bit surprised it doesn't crash :). You're only allocating four bytes (LPSTR) for filePath, whereas you need to allocate MAX_PATH bytes (GetModuleFileName uses your supplied buffer, it doesn't allocate one for you). Next, the "nSize" parameter is a DWORD, while you're passing it pointer-to-dword (and an uninitialized one, at that - GMFN() wants size-of-supplied-buffer). Third, passing FilePathLength to MessageBox... MessageBox displays strings, you're passing it an integer.
.data?
filePath BYTE MAX_PATH dup(?)
.code
invoke GetModuleFileName, 0, addr filePath, sizeof filePath
You want GetModulePath ;)
Which DLL exports that? ;)EDIT: ah, too slow, evlncrn8 beat me to it. A few comments, though: you don't need to allocate MAX_PATH+1 for the buffer, and you definitely shouldn't subtract one from sizeof when passing along the buffer length. Windows only supports MAX_PATH1 including the terminating NUL, and buffer length includes the NUL terminator.
1: unless you're using unicode functions, and the \\?\ prefix. In that case, you can do ~32.000-character paths; not necessarily a good idea, though, since 99% of Win32 software uses standard MAX_PATH :)
So, if I wanted to turn an integer into a string, would it go something like this.
mov al,",0"
mov ah, string
ror ah,"bits until ,0"
mov ah, string
ror ah,"bits until ,0"
bray,
How did you came with that? Especially the ror part.
How did you came with that? Especially the ror part.
Upon second look, it does seem somewhat silly.
Here is some psuedocode:
So GetModuleFileName returns the path to my filename into filePath BYTE MAX_PATH dup(?)
Label:
point to beginning of byte array
advance pointer and test for null
jmp if !null to label
jmp if null to alabel
alabel:
get address of pointer position
advance pointer two bytes
add string terminator to byte array
mov byte array index + pointer position offset into eax
mov eax into stringVariable
Do I now have a string?
Here is some psuedocode:
So GetModuleFileName returns the path to my filename into filePath BYTE MAX_PATH dup(?)
Label:
point to beginning of byte array
advance pointer and test for null
jmp if !null to label
jmp if null to alabel
alabel:
get address of pointer position
advance pointer two bytes
add string terminator to byte array
mov byte array index + pointer position offset into eax
mov eax into stringVariable
Do I now have a string?