peass-ng/PEASS-ng · error · Win32Exception
Win32Exception
Error message
Win32Exception
What it means
CrackNames calls DsCrackNames and throws Win32Exception when the API itself fails (returned error code is not DS_NAME_NO_ERROR), e.g. RPC failures to the DC, invalid handle, or access denied. This is an API-level failure distinct from error 306's per-name status failure: here the whole call failed.
Source
Thrown at winPEAS/winPEASexe/winPEAS/TaskScheduler/TaskEditor/Native/NTDSAPI.cs:89
if (res == null || res.Length == 0 || res[0].status != DS_NAME_ERROR.DS_NAME_NO_ERROR)
throw new SecurityException("Unable to resolve user name.");
return res[0].pName;
}
/// <summary>
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
/// </summary>
/// <param name="names">The names to convert.</param>
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
/// <param name="formatOffered">Format of the input names.</param>
/// <param name="formatDesired">Desired format for the output names.</param>
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
{
IntPtr pResult;
uint err = Ntdsapi.DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
throw new System.ComponentModel.Win32Exception((int)err);
try
{
// Next convert the returned structure to managed environment
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
return Result.Items;
}
finally
{
Ntdsapi.DsFreeNameResult(pResult);
}
}
public void Dispose()
{
uint ret = Ntdsapi.DsUnBind(ref handle);
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
}
}View on GitHub (pinned to 53fb989abc)
Solutions
- Confirm DsBind succeeded and domain controller connectivity (test RPC/LSA access to the DC)
- Check Win32Exception.NativeErrorCode to identify the specific failure (5=access denied, 1722=RPC unavailable) and fix network/permissions accordingly
- Retry on transient RPC errors after connectivity is restored
- Catch Win32Exception around CrackNames and degrade to unconverted names
Example fix
// before
var items = ntdsApi.CrackNames(new[] { name });
// after
try { items = ntdsApi.CrackNames(new[] { name }); }
catch (Win32Exception ex) { Log($"DsCrackNames failed: {ex.NativeErrorCode}"); items = null; } Defensive patterns
Strategy: try-catch
Validate before calling
using (var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)) { /* validates domain access */ } Try / catch
try { items = api.CrackNames(names); } catch (Win32Exception ex) { Log($"DsCrackNames error {ex.NativeErrorCode}"); items = null; } Prevention
- Ensure DsBind succeeded and RPC to the DC is open (port 135 + dynamic ports)
- Inspect NativeErrorCode to diagnose access vs connectivity failures
- Fall back to untranslated names on API failure
When it happens
Trigger: Calling CrackNames when the DsCrackNames P/Invoke returns a Win32 error — invalid DsBind handle, no DC reachable, RPC unavailable, or access-denied conditions — propagating the raw error code into Win32Exception at NTDSAPI.cs:89.
Common situations: Client machine not domain-joined or DC offline/firewalled (RPC ports blocked); expired machine credentials; calling name translation with a handle bound to an unavailable domain.
Related errors
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/09fe861ec0d8c6f2.
Report an issue: GitHub.