News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Find obsolete software in the registry

Started by jj2007, April 21, 2014, 04:48:56 PM

Previous topic - Next topic

jj2007

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
  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

Gunther

Jochen,

that's the thin output on my machine:

36 entries found


Gunther
You have to know the facts before you can distort them.

jj2007

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...

MtheK

  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.


dedndave

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

MtheK

  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

MtheK

  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?

dedndave

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

RuiLoureiro

 :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

jj2007

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
  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


RuiLoureiro

Jochen,
              now it is OK
              i got 35 old entries found  :t
              :biggrin:
              Thank you.

MtheK

  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.

Gunther

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
You have to know the facts before you can distort them.

jj2007

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
  Init
  GetRegKeyArray "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts", My$()
  Store "Extensions.txt", My$()
  Inkey Str$("%i extensions found", eax)
  Exit
end start

dedndave

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