Sign in to follow this  
Followers 0
markloman

Unexpected results with FileGetLongName() and possible solutions

12 posts in this topic

#1 ·  Posted (edited)

Working with spyware, trojans and virusses on a daily basis, I stumbled upon a problem with FileGetLongName() in AutoIt.

Dim $shortname= @SystemDir & "\taskdir.dll"
MsgBox(0, "before", $shortname)
$longname = FileGetLongName($shortname)
MsgBox(0, "after", $longname)

(I know, $shortname in the example above is not a shortname)

In an infected environment, $longname results in C:\WINDOWS\System32\. This should, ofcourse, result in C:\WINDOWS\System32\taskdir.dll.

Note that in a clean environment, FileGetLongName() returns the expected value.

But deleting files resolved with FileGetLongName() could result in huge system problems, since FileDelete("C:\WINDOWS\System32\") will delete the contents of @SystemDir!

I am using a workaround which does return the expected long filename in the infected environment:

Dim $filename = @SystemDir & "\taskdir.dll"
$rc = DllCall("kernel32.dll", "int", "GetFullPathName", "str", $filename, "int", 260, "str", "", "str", "")
MsgBox(0, $filename, $rc[3])

Dim $filename = @SystemDir & "\taskdir.dll"
$rc = DllCall("kernel32.dll", "int", "GetLongPathName", "str", $filename, "str", "", "int", 260)
MsgBox(0, "title", $rc[2])

Perhaps someone can look into the problem?

Edited by markloman

Share this post


Link to post
Share on other sites



But deleting files resolved with FileGetLongName() could result in huge system problems, since FileDelete("C:\WINDOWS\System32\") will delete the contents of @SystemDir!

This is not true. FileDelete() won't work on a directory and it definitely will not recursively delete the directory.

Share this post


Link to post
Share on other sites

This is not true. FileDelete() won't work on a directory and it definitely will not recursively delete the directory.

It does not recursively delete files but I bet my butt that it does delete the files below the folder!

Why not try it yourselves. Create a folder C:\folder and put some unneeded files in it. Write a small script and run it:

FileDelete("C:\folder\")

Poof, your files are gone! I had a lot of customers contacting me with unbootable systems weeks ago. They all had to restore essential .NLS files in their @SystemDir, which my AutoIt based program would normally never ever remove. At the time I rewrote my removal engine containing FileDelete() so it would not accidentially process folders (even though I did not know what was causing the "random" behaviour).

Hope it's fixed soon.

Share this post


Link to post
Share on other sites

Thats not good! I just tryed this myself and it does delete every file in the folder. Maybe this has something to do with the fix Jon made here?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thats not good! I just tryed this myself and it does delete every file in the folder. Maybe this has something to do with the fix Jon made here?

I tried it also with the same result, a DirRemove('', 1) without Removing the Directory!! I'd like to have that as an option!! :wacko:.

Edit:

Ooops ... Wild Cards, it already is :D

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

It's probably because FileDelete() supports wildcards. If I had to guess, there is an implicit "*.*" appended when using a trailing slash on a directory name. If that guess is correct, then it's not a bug although it needs to be documented. When I made my earlier statement, I had forgotten that FileDelete() accepts wildcards although admittedly I would never have thought it would implicitly use *.*, either.

markloman, I'm not sure what you really expect us to fix, though. You are dealing with infected systems. It's unfortunate that things don't work correctly but what else do you expect? It could be a rootkit or some other hijack attempt causing the function to return unexpected data.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

; This should delete all the files
FileDelete("C:\folder\*.*")
; This should NOT, it should actually return an error
FileDelete("C:\folder\")

Edited by big_daddy

Share this post


Link to post
Share on other sites

I don't see why this is a problem. The functionality has probably been in AutoIt since the utility function was written and it's only just now been realized. All that I think needs done is a mention in the helpfile that when passed a directory, FileDelete() will delete all the files in that directory by using the "*.*" wildcard.

In 3 years, one person has found the functionality, I hardly call that a problem big enough to warrant ripping the code out for.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I am aware of the fact that on infected systems, unexpected things can occur. That is also why I jumped on the idea of fortifying my removal engine a bit - making sure FileDelete() doesn't get folders to eat.

I also agree that the FileDelete() function works fine as it does, even though (for me) it was unexpected. Just add a note in the manual to elaborate things a bit.

But let's not forget the main reason why I created this thread. I think there is a problem with FileGetLongName(). My mentioned workarounds work great in the infected VMware environment, so I fail to see why FileGetLongName() comes up with such a crooked result when it is asked to do its magic in the same script as my workaround. How does the internal AutoIt FileGetLongName() command work?

In the meantime I banned FileGetLongName() from my scripts.

Edited by markloman

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Try using the second parameter of FileGetLongName(). It seems to force the code to use similar to what you are doing with DllCall(). For some reason, using it without that flag goes a much different route that I don't understand the purpose of. FileGetLongName($shortname, 1) should work, however.

Edit: Correct brain-dead mistake.

Edited by Valik

Share this post


Link to post
Share on other sites

Working with spyware, trojans and virusses on a daily basis, I stumbled upon a problem with FileGetLongName() in AutoIt.

Dim $shortname= @SystemDir & "\taskdir.dll"
MsgBox(0, "before", $shortname)
$longname = FileGetLongName($shortname)
MsgBox(0, "after", $longname)

(I know, $shortname in the example above is not a shortname)

In an infected environment, $longname results in C:\WINDOWS\System32\. This should, ofcourse, result in C:\WINDOWS\System32\taskdir.dll.

Note that in a clean environment, FileGetLongName() returns the expected value.

Obviously you did some checking to validate the return of "C:\WINDOWS\System32\". My query would be that did FileGetLongName actually return an @error of 1 to warn that it returned a folder path rather then a file path? If @error were not warning of this, then it could be a blind tragic event for the script and a concern.

Share this post


Link to post
Share on other sites

@error = 0 when FileGetLongName() returned the malformed result:

Posted Image

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0