3) samsrv!SampUpdateEncryption() 用IDA Pro 4.6.0.785逆向英文版XP SP1的samsrv!SampUpdateEncryption: 下面是C风格的伪代码: -------------------------------------------------------------------------- /* * samsrv.dll中定义的全局变量 */ extern PSAM_DOMAIN SampDefinedDomains; /* * 我猜不出var_9、var_10的意义所在,也没时间逆得更深,暂时先不管这两个变量 * 了,以后有时间再来修正。 * * status不是栈式局部变量,在汇编代码中不直接对应某个内存位置。 * * 标号SampUpdateEncryption_exit不直接对应汇编代码中的标号,毕竟逆向是试着 * 还原最初的C代码,要考虑编译器的工作。 */ NTSTATUS __stdcall SampUpdateEncryption ( HANDLE samhandle // 第01形参,[EBP+0x008] ) { BOOL nomoredata; // 第01个局部变量,[EBP-0x001] // 由于对齐优化的缘故实际将占去4字节 HANDLE ContextHandle; // 第02个局部变量,[EBP-0x008] PSAM_DOMAIN_USER_ENUMERATION DomainUserEnumeration; // 第03个局部变量,[EBP-0x00C] HANDLE DomainHandle; // 第04个局部变量,[EBP-0x010] PSAM_PRIVATE_USER_DATA PrivateUserData; // 第05个局部变量,[EBP-0x014] HANDLE SamHandle; // 第06个局部变量,[EBP-0x018] DWORD UserCount; // 第07个局部变量,[EBP-0x01C] HANDLE EnumerationHandle; // 第08个局部变量,[EBP-0x020] var_9; // 第09个局部变量,[EBP-0x024] var_10; // 第10个局部变量,[EBP-0x028] NTSTATUS status; DWORD count; DomainHandle = ( HANDLE )NULL; ContextHandle = ( HANDLE )NULL; SamHandle = ( HANDLE )NULL; EnumerationHandle = ( HANDLE )NULL; DomainUserEnumeration = ( PSAM_DOMAIN_USER_ENUMERATION )NULL; nomoredata = FALSE; PrivateUserData = ( PSAM_PRIVATE_USER_DATA )NULL; if ( NULL == samhandle ) { status = SamIConnect ( 0, &SamHandle, // [out]参数 0x000F003F, // Access Mask,参SamrConnect2()的Ethereal解码 1 ); if ( !NT_SUCCESS( status ) ) { goto SampUpdateEncryption_exit; } samhandle = SamHandle; } status = SamrOpenDomain ( samhandle, 0x00000301, // Access Mask,参Ethereal解码 SampDefinedDomains->DomainSid, &DomainHandle // [out]参数 ); if ( !NT_SUCCESS( status ) ) { goto SampUpdateEncryption_exit; } var_9 = DomainHandle->Unkown_0E0; /* * 下面这段我实在没法逆成C风格的伪代码,SAM_DOMAIN结构未明。显然var_9 * 是个Index,0x340是sizeof( struct xxx )。但结构数组的偏移未必是0x19E, * 注意到+0x344处是DomainSid。DomainSid很可能并不直接是SAM_DOMAIN结构 * 的成员,而是第一个xxx结构的成员。SAM_DOMAIN结构中包含xxx结构数组。 * 此处无关本次意图,放弃之,下面的汇编代码不是直接反汇编的结果。 */ status = 0; __asm { test byte ptr [var_9 * 0x340 + SampDefinedDomains + 19Eh],1 jz offset SampUpdateEncryption_exit } do { status = SamrEnumerateUsersInDomain ( DomainHandle, // Context Handle &EnumerationHandle, // [in/out]参数,Resume Handle 0, // filter,Access Mask &DomainUserEnumeration, // [out]参数 0x0000FFFF, // 意义未明,似乎对应Pref MaxSize &UserCount // [out]参数 ); if ( !NT_SUCCESS( status ) ) { goto SampUpdateEncryption_exit; } /* * from ntstatus.h(\WINDDK\2600.1106\inc\ddk\wxp\) * * Returned by enumeration APIs to indicate more information is * available to successive calls. * * #define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L) */ if ( STATUS_MORE_ENTRIES != status ) { nomoredata = TRUE; } count = 0; while ( count < UserCount ) { status = SampAcquireWriteLock(); if ( !NT_SUCCESS( status ) ) { /* * 注意这是do-while循环里嵌套while循环 */ goto SampUpdateEncryption_exit; } SampSetTransactionDomain( var_9 ); status = SampCreateAccountContext ( 4, DomainUserEnumeration->DomainUser[count], 1, 0, 1, &ContextHandle // [out]参数 ); if ( !NT_SUCCESS( status ) ) { /* * 与SampAcquireWriteLock()配对 */ SampReleaseWriteLock( FALSE ); goto SampUpdateEncryption_exit; } status = SampGetPrivateUserData ( ContextHandle, &var_10, &PrivateUserData ); if ( !NT_SUCCESS( status ) ) { SampReleaseWriteLock( FALSE ); goto SampUpdateEncryption_exit; } status = SampSetPrivateUserData ( ContextHandle, var_10, PrivateUserData ); MIDL_user_free( PrivateUserData ); PrivateUserData = NULL; if ( !NT_SUCCESS( status ) ) { SampReleaseWriteLock( FALSE ); goto SampUpdateEncryption_exit; } SampStoreObjectAttributes ( ContextHandle, NULL ); /* * 与SampCreateAccountContext()配对 */ status = SampDeleteContext( ContextHandle ); ContextHandle = NULL; if ( !NT_SUCCESS( status ) ) { SampReleaseWriteLock( FALSE ); goto SampUpdateEncryption_exit; } SampSetTransactionWithinDomain( NULL ); /* * 与SampAcquireWriteLock()配对 */ status = SampReleaseWriteLock( TRUE ); if ( !NT_SUCCESS( status ) ) { goto SampUpdateEncryption_exit; } count++; } /* end of while */ SamIFree_SAMPR_ENUMERATION_BUFFER ( ( PSAM_ENUMERATION_BUFFER )DomainUserEnumeration ); DomainUserEnumeration = NULL; } while ( FALSE == nomoredata ); SampUpdateEncryption_exit: if ( NULL != ContextHandle ) { /* * 与SampCreateAccountContext()配对 */ SampDeleteContext( ContextHandle ); } if ( NULL != DomainHandle ) { /* * 与SamrOpenDomain()配对 */ SamrCloseHandle( &DomainHandle ); } if ( NULL != SamHandle ) { /* * 与SamIConnect()配对 */ SamrCloseHandle( &SamHandle ); } if ( NULL != DomainUserEnumeration ) { SamIFree_SAMPR_ENUMERATION_BUFFER ( ( PSAM_ENUMERATION_BUFFER )DomainUserEnumeration ); } return( status ); } /* end of SampUpdateEncryption */ -------------------------------------------------------------------------- 对比pwdump2/samdump.c,不再神密了吧,尤其是貌似突兀的STATUS_MORE_ENTRIES, 这可是正经的NTSTATUS值! SamIFree_SAMPR_ENUMERATION_BUFFER()不只用于DomainUserEnumeration,因此其形 参类型不是PSAM_DOMAIN_USER_ENUMERATION,调用时可能需要对指针做强制类型转换。