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,调用时可能需要对指针做强制类型转换。