首页
社区
课程
招聘
[旧帖] [求助]一个win32汇编的程序,折腾一天没折腾出来,前辈们帮看看……谢谢了 0.00雪花
发表于: 2011-10-6 00:55 1556

[旧帖] [求助]一个win32汇编的程序,折腾一天没折腾出来,前辈们帮看看……谢谢了 0.00雪花

2011-10-6 00:55
1556
		.386
		.model flat,stdcall
		option casemap:none
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
include		windows.inc
include		kernel32.inc
includelib	kernel32.lib
include		user32.inc
includelib	user32.lib
include		Stdlib.Inc
includelib	Stdlib.lib
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
		.const
szPathBmp	db	'*.bmp',0
szPathJpg	db	'*.jpg',0
		.data?
dwCount		dd	?
hFindFile		dd	?
szBuffer		db	256 	dup (?)
szName		db	MAX_PATH	dup (?)
szBufferName	db	2048	dup(?)
dwRand		dd	?
dwFileCount	dd	?
dwAddr		dd	?
stWin32FindData	WIN32_FIND_DATA	<?>
		.code
_FindBmpFiles	proc	;查找bmp文件
		invoke	FindFirstFile,offset szPathBmp,offset stWin32FindData 
		.if	eax !=	INVALID_HANDLE_VALUE	;如果找到第一个bmp文件,保存句柄,进行FindNextFile
			mov	hFindFile,eax
			.while	TRUE
				inc	dwCount
				invoke	StrCat,offset szBufferName,offset stWin32FindData.cFileName   ;把找到的文件的文件名拼接到缓存区里
				invoke	FindNextFile,hFindFile,offset stWin32FindData
				.break	.if 	eax == 	FALSE
			.endw
			invoke	FindClose,hFindFile	;关闭文件句柄
		.endif
		ret
_FindBmpFiles 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_FindJpgFiles	proc	;注释类似与_FindBmpFiles
		invoke	FindFirstFile,offset szPathJpg,offset stWin32FindData 
		.if	eax !=	INVALID_HANDLE_VALUE
			mov	hFindFile,eax
			.while	TRUE
				inc	dwCount
				invoke	StrCat,offset szBufferName,offset stWin32FindData.cFileName
				invoke	FindNextFile,hFindFile,offset stWin32FindData
				.break	.if 	eax == 	FALSE
			.endw
			invoke	FindClose,hFindFile
		.endif
		ret
_FindJpgFiles 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_ChangeWall	proc
		invoke	Randomize
		invoke	Random,dwCount                   ;产生随机数
		mov	ebx,MAX_PATH
		mul	ebx			;这里有个问题:我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来
		mov	ebx,offset szBufferName	;存储文件名的,不是以MAX_PATH长度来存储的,那么,想取出缓存区里任意一个文件名的
		add	eax,ebx			;的话,应该如何操作呢?想了一天了,还是没想明白……初学者……
		invoke	SystemParametersInfo,SPI_SETDESKWALLPAPER,0,eax,SPIF_UPDATEINIFILE
		ret
_ChangeWall 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
start:		call	_FindBmpFiles
		call	_FindJpgFiles
		call	_ChangeWall
		invoke	ExitProcess,NULL 
		end	start


问题的描述已经在注释里面了!程序的功能就是找到图片文件,然后随机的把其中一个图片设置成桌面背景!
我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来存储文件名的,不是以MAX_PATH长度来存储的,那么,想取出缓存区里任意一个文件名的话,应该如何操作呢?想了一天了,还是没想明白……初学者……

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
首先你找bmp  jpg文件就不成功。。。后面的就不用说了。。。怎么设置了。。。
2011-10-6 01:23
0
雪    币: 29
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
在你的文件里面是可以找到的。。。
2011-10-6 01:25
0
雪    币: 56
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
可以找到文件啊,可是放到缓存区里面的时候,文件名是挨着放的,并不是按照MAX_PATH的尺寸放的!不知道该怎么办了!

谁还可以知道一下啊!郁闷死了!
2011-10-6 09:44
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
invoke  StrCat,offset szBufferName,offset stWin32FindData.cFileName,
你每次都这样连接,不能说不行,不好解析吧,这种做法就像下面这样:
C:\1.jpgC:\2.jpg;
最好是在中间加分隔符0x00;
"C\:1.jpg",‘\0' , "C:\2.jpg"  .....................
2011-10-6 10:48
0
雪    币: 23
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
要么把结果转成等长度存储(MAX_PATH-strlen,把后面补齐,或跳过);
或者单独在定义一个地址数组,记录每个文件路径的起始位置。
2011-10-6 10:48
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
    .586
    .model flat,stdcall
    option casemap:none
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
include    windows.inc
include    kernel32.inc
includelib  kernel32.lib
include    user32.inc
includelib  user32.lib
;include    Stdlib.Inc
;includelib  Stdlib.lib
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
    .const
szPathBmp  db  '*.bmp',0
szPathJpg  db  '*.jpg',0
    .data?
dwCount    dd  ?
hFindFile    dd  ?
szBuffer    db  256   dup (?)
szName    db  MAX_PATH  dup (?)
szBufferName  db  2048  dup(?)
dwRand    dd  ?
dwFileCount  dd  ?
dwAddr    dd  ?
stWin32FindData  WIN32_FIND_DATA  <?>
    .code
_FindBmpFiles  proc  ;查找bmp文件
    invoke  FindFirstFile,offset szPathBmp,offset stWin32FindData 
	mov		esi,offset szBufferName
    .if  eax !=  INVALID_HANDLE_VALUE  ;如果找到第一个bmp文件,保存句柄,进行FindNextFile
      mov  hFindFile,eax
      .while  TRUE
        inc  dwCount
        invoke  lstrcat,esi,offset stWin32FindData.cFileName   ;把找到的文件的文件名拼接到缓存区里
		invoke	lstrlen,offset stWin32FindData.cFileName
		add		esi,eax
		inc		esi
        invoke  FindNextFile,hFindFile,offset stWin32FindData
        .break  .if   eax ==   FALSE
      .endw
      invoke  FindClose,hFindFile  ;关闭文件句柄
    .endif
    ret
_FindBmpFiles   endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_FindJpgFiles  proc  ;注释类似与_FindBmpFiles
    invoke  FindFirstFile,offset szPathJpg,offset stWin32FindData 
    .if  eax !=  INVALID_HANDLE_VALUE
      mov  hFindFile,eax
      .while  TRUE
        inc  dwCount
        invoke  lstrcat,esi,offset stWin32FindData.cFileName
		invoke	lstrlen,offset stWin32FindData.cFileName
		add		esi,eax
		inc		esi
        invoke  FindNextFile,hFindFile,offset stWin32FindData
        .break  .if   eax ==   FALSE
      .endw
      invoke  FindClose,hFindFile
    .endif
    ret
_FindJpgFiles   endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_ChangeWall  proc
;    invoke  Randomize
 ;   invoke  Random,dwCount                   ;产生随机数
 ;   mov  ebx,MAX_PATH
  ;  mul  ebx      ;这里有个问题:我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来
	rdtsc			;cpu从开机到此指令的运行周期
	movzx	eax,al  ;模拟随机数和求模,
	mov	 ecx,dwCount
	.while eax>ecx
		sub  eax,ecx
	.endw
	mov		ecx,eax		; 最后的ECX <= 找到的文件数,然后就是找一个字符的结束标志 0x00
	
	dec		ecx		
	xor		al,al
	mov		edi,offset szBufferName
	.while	ecx		
		mov		al,byte ptr [edi]
		inc		edi;
		.if		!al
			dec		ecx   ; 找到一个结束标志 ecx -= 1
		.endif
	.endw
    mov  ebx,edi  
	xor	eax,eax
    add  eax,ebx 	;这里不明白为何要+eax,为保险起见,清零了
    invoke  SystemParametersInfo,SPI_SETDESKWALLPAPER,0,eax,SPIF_UPDATEINIFILE
    ret
_ChangeWall   endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
start:    
	invoke RtlZeroMemory,offset szBufferName,2048
	call  _FindBmpFiles
    call  _FindJpgFiles
    call  _ChangeWall
    invoke  ExitProcess,NULL 
    end  start
2011-10-6 12:26
0
雪    币: 56
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
问题,这样的话,只能让程序数0然后确定是第几个文件了吧?
2011-10-6 13:07
0
雪    币: 56
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
十分感谢!不过……程序执行的时候挂掉了……CPU使用率居高不下!
还有,由于我才疏学浅,_ChangeWall 这个函数居然没看懂……
2011-10-6 13:13
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
我测试的时候没这个问题。可以换背景。
  rdtsc      ;cpu从开机到此指令的运行周期
  movzx  eax,al  ;模拟随机数和求模,这里只取了al作为随即数
  mov   ecx,dwCount

  .while eax>ecx
    sub  eax,ecx  ;循环减法,就是求模 eax%dwCount, 本来应该用除法 ,但是忘记了余数在哪儿,就改用减法来求模,  用除法还有一个问题就是,如果整除,后面就有问题了,所以整除了,就表示应该取最后一个路径
  .endw
;上面这个循环可以换为
xor edx,edx
div ecx
mov eax,edx
.if !eax
   mov   eax,dwCount
.endif
mov ecx, eax

;后面就是数零了,每个字符串以0x00结尾
dec    ecx    ;ecx -= 1 好理解,假设ecx == 1,表示要取第一个路径,后面的代码执行后却是取第二个路径,先减 1,后面的 while 不会执行, 第一个路径就是edi了
  xor    al,al
  mov    edi,offset szBufferName
  .while  ecx   
    mov    al,byte ptr [edi]  ;这里就开始找0了
    inc    edi;
    .if    !al
      dec    ecx   ; 找到一个结束标志0, ecx -= 1,
    .endif
  .endw
2011-10-6 18:03
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
上面的代码还有一个问题就是,你的两个函数
  call  _FindBmpFiles
    call  _FindJpgFiles
里面,原来并没有用过esi,Windows函数调用也不会改变EDI,ESI。_FindBmpFiles结束后 esi 的值并没有改变,直接 在  _FindJpgFiles 里面继续连接字符串,这种方法是不可取的,最好在第一个函数里面保存。
我测试是在Win7,下,没出现CPU高的情况。
2011-10-6 18:23
0
雪    币: 56
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
		.386
		.model flat,stdcall
		option casemap:none
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
include		windows.inc
include		kernel32.inc
includelib	kernel32.lib
include		user32.inc
includelib	user32.lib
include		Stdlib.Inc
includelib	Stdlib.lib
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
ICO_MAIN	equ	1000h
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
		.const
szPathBmp	db	'*.bmp',0
szPathJpg	db	'*.jpg',0
szError		db	'未找到任何bmp和jpg的文件',0dh,0ah,
			'程序将退出',0dh,0ah,
			'谢谢使用',0dh,0ah,
			'BY:GLCWOLF',0
szErrorCap	db	'查找图片失败',0
		.data
szTest1		db	'%d',0
szTest2		db	'%s',0
szBufferTest	db	128 dup (?)
		.data?
dwCount		dd	?
hFindFile		dd	?
szBuffer		db	256 	dup (?)
szName		db	MAX_PATH	dup (?)
szBufferName	db	10000	dup(?)
dwRand		dd	?
dwFileCount	dd	?
dwAddr		dd	?
stWin32FindData	WIN32_FIND_DATA	<?>
dwNameAddr	dd	?
		.code
_FindBmpFiles	proc	uses esi;查找bmp文件
		invoke	FindFirstFile,offset szPathBmp,offset stWin32FindData 
		.if	eax !=	INVALID_HANDLE_VALUE	;如果找到第一个bmp文件,保存句柄,进行FindNextFile
			mov	hFindFile,eax
			mov	esi,offset szBufferName
			.while	TRUE
				inc	dwCount
				invoke	StrCpy,esi,offset stWin32FindData.cFileName   ;把找到的文件的文件名拼接到缓存区里
				add	esi,sizeof stWin32FindData.cFileName
				mov	dwNameAddr,esi
				invoke	FindNextFile,hFindFile,offset stWin32FindData
				.break	.if 	eax == 	FALSE
			.endw
			invoke	FindClose,hFindFile	;关闭文件句柄
		.endif
		ret
_FindBmpFiles 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_FindJpgFiles	proc	uses esi;注释类似与_FindBmpFiles
		.if	dwCount ==0
			mov	esi,offset szBufferName   	;如果没找到BMP图片,那么把缓存区的地址给esi
		.else
			mov	esi,dwNameAddr		;如果找到了BMP,那么接着找到的BMP文件的后面放置JPG的文件名
		.endif
		invoke	FindFirstFile,offset szPathJpg,offset stWin32FindData 
		.if	eax !=	INVALID_HANDLE_VALUE
			mov	hFindFile,eax
			.while	TRUE
				inc	dwCount
				invoke	StrCpy,esi,offset stWin32FindData.cFileName
				add	esi,sizeof stWin32FindData.cFileName
				invoke	FindNextFile,hFindFile,offset stWin32FindData
				.break	.if 	eax == 	FALSE
			.endw
			invoke	FindClose,hFindFile	
		.endif
		
		ret
_FindJpgFiles 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
_ChangeWall	proc
		invoke	Randomize
		invoke	Random,dwCount                   ;产生随机数
		mov	ebx,sizeof stWin32FindData.cFileName
		mul	ebx			;这里有个问题:我把MAX_PATH长度的文件名,放到缓存区里面,但是缓存区是以实际长度来
		mov	ebx,offset szBufferName	;存储文件名的,不是以MAX_PATH长度来存储的,那么,想取出缓存区里任意一个文件名的
		add	eax,ebx			;的话,应该如何操作呢?想了一天了,还是没想明白……初学者……
		invoke	SystemParametersInfo,SPI_SETDESKWALLPAPER,0,eax,SPIF_UPDATEINIFILE
		ret
_ChangeWall 	endp
_ErrorInfo	proc
		invoke	MessageBox,NULL,offset szError,offset szErrorCap,MB_OK
		invoke	ExitProcess,NULL 
		ret
_ErrorInfo 	endp
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
start:		invoke	LoadIcon,NULL,ICO_MAIN
		invoke	SendMessage,NULL,WM_SETICON,ICON_BIG or ICON_SMALL,eax
		call	_FindBmpFiles
		call	_FindJpgFiles
		.if	dwCount > 0
			call	_ChangeWall
		.else
			call	_ErrorInfo
		.endif
		invoke	ExitProcess,NULL 
		end	start


方法和你的有一些出入!我实在是看不懂你的程序啊……我刚学!不好意思……

但是现在有个新问题:

设置桌面的时候,SystemParametersInfo 如何让它支持JPG的图片呢?
兄台,你知道吗?
2011-10-6 18:38
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
SystemParametersInfo没用过。查了网上的资料,没C或者C++的,这个函数貌似不可以设置jpeg为墙纸。
2011-10-6 21:13
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
貌似要汇编真的很难啊啊
2011-10-6 21:20
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
也不是很难,多用OD就知道了。
2011-10-6 22:19
0
游客
登录 | 注册 方可回帖
返回
//