One less known fact about the registry is that all entries have a timestamp, allowing you to control when the key was last written. This information may come in handy:
- to identify new entries (malware??)
- to find old and obsolete entries.
For the latter case, here a simple example looking at HKCU\Software. Attention the fact that some entries are very old does not automatically imply they are obsolete. In case of doubt, check if the software still exists on your PC.
The attached proggie simply displays entries older than two years. It does not modify the registry.
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetRegKeyArray "HKCU\Software", My$(), LastMod()
xchg eax, ebx
For_ ecx=0 To ebx-1 ; show only entries over two years old
.if Age(LastMod(ecx), d)>2*365 ; h=hours (valid units: d/h/m/s/ms/µs)
PrintLine fDate$(LastMod(ecx)), ", ", fTime$(LastMod(ecx)), Tb$, My$(ecx)
.endif
Next
Inkey Str$("%i entries found", ebx)
Exit
end start
Sample output:
31.07.2008, 18:14:26 Adobe
08.11.2009, 14:48:42 CDBurnerXP
25.02.2009, 20:19:47 Donkey
27.01.2010, 21:12:12 Foxit Software
29.12.2011, 18:44:48 GeneSys Editor Plus
15.02.2010, 18:01:36 InstallShield
02.01.2010, 09:34:03 KetilO
07.04.2009, 01:37:56 MasmEd1000
05.12.2008, 23:27:53 Mozilla
22.01.2010, 19:36:09 WinZip Computing
Jochen,
that's the thin output on my machine:
36 entries found
Gunther
I've got 89, but this notebook is already 8 years old. Try with Age(LastMod(ecx), d)>30 to see all entries older than one month...
As an FYI, my DSNTODAY system:
http://masm32.com/board/index.php?topic=2117.0
the REGTODAY program, does what your former point indicated (to find
any entries added by, say, malware). It can also search on a generic date.
this machine is almost 10 years old
13.10.2010, 05:38:05 Google
13.10.2010, 05:38:05 Intel
16.10.2010, 13:08:20 InterVideo
16.10.2010, 01:07:18 Lake
13.10.2010, 05:38:05 Netscape
13.10.2010, 05:38:05 Sony
16.10.2010, 13:08:20 Sony Corporation
21.10.2010, 15:56:17 Trend Micro
57 entries found
it has an old version of InterVideo WinDVD, which i use all the time :P
Trend Micro is HiJackThis, i guess
I run this .BAT to get a TOD of everything (by year):
del REGTODAY.log
set /A XYEAR=2014
set /A XLOOP=35
:DOAGAIN
call PARMIN.bat "%XYEAR% " >DSNTODAY.tim
call REGTODAY.bat "" N Y
if %XLOOP% EQU 0 goto DONE
set /A XYEAR=XYEAR - 1
set /A XLOOP=XLOOP - 1
GOTO DOAGAIN
:DONE
del DSNTODAY.TIM
Regarding the registry, perhaps someone can explain this weird result I get.
Basically, this:
INVOKE RegEnumKeyEx,
REGKEY,
REGINDEX,
OFFSET REGNAME,
OFFSET REGNAMEL,
NULL,
OFFSET REGCLASS,
OFFSET REGCLASSL,
OFFSET SLEEPONEOF
loads up REGNAME with this:
'2eaceb5f'h (.⌐ë_) w/a length in REGNAMEL of 4
which I try to open:
Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.⌐ë_ (w/ASCIIZ)
INVOKE RegOpenKeyEx,
REGKEY,
OFFSET SUBKEYNAME,
0,
KEY_READ,
OFFSET KYHANDLEXXX
but it fails w/rc=2 (ERROR_FILE_NOT_FOUND)?
3 of the above fields are aligned (REGNAME at 4K, REGCLASS and SUBKEYNAME at 16).
KEY_READ+KEY_WOW64_32KEY fails miserably (everything gets rc=5), while
KEY_READ+200h (supposedly s/b the same?) works but doesn't fix the rc=2.
I can't figure out why Regedt32.exe works:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.⌐ë_]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.⌐ë_\OpenWithList]
but my program using WINAPI fails? Is this some type of special, hidden entry that needs special processing? Is this a UNICODE entry? If so, do I need to somehow translate it or somehow indicate it to the WINAPI? And if so, how do I know that it's UNICODE? I only say this 'cause, when I save this text document, NOTEPAD wants it in UNICODE format but doesn't if I take out that weird entry.
Only 1 of my laptops has this entry, and this is the only rc=2 failure I get in the entire registry of a few hundred thousand entries (actually, 2 of the same in HKEY_CURRENT_USER and HKEY_USERS). For now, I just show and ignore it.
Comments?
it may very well be that it is terminated with a double null :P
the way to access them is to use the NtReg/ZwReg functions
which are somewhat different than the API counterparts
first, strings are almost always UNICODE when using NtReg functions
second, UNICODE strings used with NtReg functions should always be word-aligned
finally, some things are accessed in structures where the API might use direct variables
the API functions are generally wrappers that call the NtReg functions
the interface mechanics are somewhat simpler
:biggrin:
Hi Jochen,
This is what i got
39 entries found
This result doesnt say anything ...
How do we get something like your "Sample Output", Jochen ?
:t
Hi Rui,
You seem to have only relatively new stuff - and the #entries means "all", not "old ones only". My fault. Here is a version that looks at entries old one month and more, and counts only the old ones:
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetRegKeyArray "HKCU\Software", My$(), LastMod()
xchg eax, ebx
xor esi, esi
For_ ecx=0 To ebx-1 ; show only entries over one month old
.if Age(LastMod(ecx), d)>30 ; h=hours (valid units: d/h/m/s/ms/µs)
inc esi
PrintLine fDate$(LastMod(ecx)), ", ", fTime$(LastMod(ecx)), Tb$, My$(ecx)
.endif
Next
Inkey Str$("%i old entries found", esi)
Exit
end start
Jochen,
now it is OK
i got 35 old entries found :t
:biggrin:
Thank you.
Writing the double-null didn't fix the rc=2.
However, I finally fixed the problem: to resolve this UNICODE stuff,
I have to maintain a shadow using RegEnumKeyExW in parallel with RegEnumKeyEx. So, when the rc=2 occurs, I try again with RegOpenKeyExW
using the shadow (wide) subkey name, which then works. Adding this, tho, is extremely CPUR-intensive for just 1 record (in my case; apx 10-fold), so I made resolving it an optional "feature".
Reg.exe can show this, but, when pasting from a .reg export into a DOS Prompt,
it works fine, but if pasting into a .BAT, it's very finicky; I have to save it
using my 3+ decades-old hex editor which then lets Reg.exe find it. When using
NOTEPAD, it wants it saved in UNICODE format, which makes the .BAT un-runnable, and saving it in ANSI makes Reg.exe fail in that it can't find it.
Hi MtheK,
Quote from: MtheK on May 04, 2014, 12:56:02 AM
Reg.exe can show this, but, when pasting from a .reg export into a DOS Prompt,
it works fine, but if pasting into a .BAT, it's very finicky; I have to save it
using my 3+ decades-old hex editor which then lets Reg.exe find it. When using
NOTEPAD, it wants it saved in UNICODE format, which makes the .BAT un-runnable, and saving it in ANSI makes Reg.exe fail in that it can't find it.
that sounds a bit strange.
Gunther
Hi MThek,
Looks like you've got a malformed extension. What do you find with this snippet (source & exe attached)?
include \masm32\MasmBasic\MasmBasic.inc ; download (http://masm32.com/board/index.php?topic=94.0)
Init
GetRegKeyArray "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts", My$()
Store "Extensions.txt", My$()
Inkey Str$("%i extensions found", eax)
Exit
end start
there is also an issue of registry virtualization
many of the keys that appear in the registry are virtually created at boot time
as an example....
if i want to VIEW an item, i might look in HKEY_CLASSES_ROOT
if i want to WRITE the same item, i might want to access HKEY_LOCAL_MACHINE\Software\Classes
or HKEY_CURRENT_USER\Software\Classes
The attached is how I got the paste/.BAT issue...
It seems pretty obvious that you have registered a Unicode extension. Can you export the keys as standard reg file, zip it and post it here?
BTW what kind of file does this magic extension open?
see REGTODAY.log for comments...
it may be a remnant of a virus that was otherwise successfully removed