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?
Posted on 2010-01-14 18:04:20 by bray
I did some research on MSDN and found a few functions which can access the registry through ADVAPI32.lib.

  __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

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?
Posted on 2010-01-17 15:07:43 by bray
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!
Posted on 2010-01-19 13:44:22 by bray
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).
Posted on 2010-01-20 06:25:20 by f0dder
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%
Posted on 2010-01-21 16:56:10 by bray
Also, I wanted to test GetModuleFileName and produced the following

.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


FilePath LPSTR ?
FilePathLength DWORD ?

    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?
Posted on 2010-01-21 21:43:41 by bray
You want GetModulePath ;)
Don't be too worried about data types defined by C.
They use a dozen names to define the same primitives.
Posted on 2010-01-21 23:26:00 by Homer
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 (?)


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.
Posted on 2010-01-22 07:17:38 by evlncrn8
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?

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.

filePath BYTE MAX_PATH dup(?)
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 :)
Posted on 2010-01-22 07:29:41 by f0dder
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"
Posted on 2010-01-24 11:44:39 by bray

How did you came with that? Especially the ror part.
Posted on 2010-01-24 18:37:19 by baldr
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(?)

point to beginning of byte array
advance pointer and test for null
jmp if !null to label
jmp if null to 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?
Posted on 2010-01-25 14:36:05 by bray