Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Забанен


Сообщения: 27
Благодарности: 2

Профиль | Цитировать


Пацаны! Это ж ох**ть крутая вещь обращаться к драйверу из pwsh без сторонних тулз и дллэлок! Надеюсь greg zakharov не будет против если скопипижжу его код отсюда прямо сюда.
Наглый копипаст
Код: Выделить весь код
using namespace System.Text
using namespace System.Reflection
using namespace System.ComponentModel
using namespace System.Reflection.Emit
using namespace System.Linq.Expressions
using namespace System.Runtime.InteropServices
#################################################################################################
#############     Accessing Beep driver without third party tools and assemblies     ############
#############                        Add-Type cmdlet free                            ############
#############                                                                        ############
#################################################################################################
if (![Environment]::Is64BitOperatingSystem) {
  throw [InvalidOperationException]::new('PoC requires x64 system.')
}

$requires = @{GetProcAddress = [IntPtr]::Zero; GetModuleHandleW = [IntPtr]::Zero}
$ib = ($ps = Get-Process -Id $pid).Modules.Where{$_.ModuleName -match 'kernel32'}.BaseAddress
$ps.Dispose()

$va = [Marshal]::ReadInt32([IntPtr]([Marshal]::ReadInt32($ib, 0x3C) + $ib.ToInt64() + 0x88))
$nn = [Marshal]::ReadInt32($ib, $va + 0x18) # number of names
$af = [Marshal]::ReadInt32($ib, $va + 0x1C) # address of functions
$an = [Marshal]::ReadInt32($ib, $va + 0x20) # address of names

$tmp = $ib.ToInt64()
(0..($nn - 1)).ForEach{
  if (($name = [Marshal]::PtrToStringAnsi(
    [IntPtr]($tmp + [Marshal]::ReadInt32([IntPtr]($tmp + $an + $_ * 4)))
  )) -in $requires.Keys) {
    $requires[$name] = $tmp + [Marshal]::ReadInt32([IntPtr]($tmp + $af + $_ * 4))
  }
}

$delegate = {
  param([IntPtr]$a, [Type]$p, [CallingConvention]$cc = 'StdCall')

  end {
    $method = $p.GetMethod('Invoke')
    $returntype, $parameters = $method.ReturnType, $method.GetParameters().ParameterType
    $il = ($holder = [DynamicMethod]::new('Invoke', $returntype, $parameters, $p)).GetILGenerator()

    if ($parameters) {
      (0..($parameters.Length - 1)).ForEach{ $il.Emit([OpCodes]::ldarg, $_) }
    }
    $il.Emit([OpCodes]::ldc_i8, $a.ToInt64())
    $il.EmitCalli([OpCodes]::calli, $cc, $returntype, $parameters)
    $il.Emit([OpCodes]::ret)

    $holder.CreateDelegate($p)
  }
}

$delegates = {
  param([String]$d, [ScriptBlock]$s)

  end {
    $GetProcAddress = & $delegate $requires.GetProcAddress ([Func[IntPtr, String, IntPtr]])
    $GetModuleHandle = & $delegate $requires.GetModuleHandleW ([Func[[Byte[]], IntPtr]])

    if (($mod = $GetModuleHandle.Invoke([Encoding]::Unicode.GetBytes($d))) -eq [IntPtr]::Zero) {
      throw [DllNotFoundException]::new("Cannot find $d library.")
    }

    $funcs = @{}
    for ($i, $m, $fn, $p = 0, ([Expression].Assembly.GetType(
        'System.Linq.Expressions.Compiler.DelegateHelpers'
       ).GetMethod('MakeNewCustomDelegate', [BindingFlags]'NonPublic, Static')
       ), [Marshal].GetMethod('GetDelegateForFunctionPointer', ([IntPtr])),
       $s.Ast.FindAll({$args[0].CommandElements}, $true).ToArray();
       $i -lt $p.Length; $i++
    ) {
      $fnret, $fname = ($def = $p[$i].CommandElements).Value

      if (($fnsig = $GetProcAddress.Invoke($mod, $fname)) -eq [IntPtr]::Zero) {
        throw [InvalidOperationException]::new("Cannot find $fname signature.")
      }

      $fnargs = $def.Pipeline.Extent.Text
      [Object[]]$fnargs = [String]::IsNullOrEmpty($fnargs) ? $fnret : (
        ($fnargs -replace '\[|\]' -split ',\s+').ForEach{
          $_.StartsWith('_') ? (Get-Variable $_.Remove(0, 1) -ValueOnly) : $_
        } + $fnret
      )

      $funcs[$fname] = $fn.MakeGenericMethod(
        [Delegate]::CreateDelegate([Func[[Type[]], Type]], $m).Invoke($fnargs)
      ).Invoke([Marshal], $fnsig)
    }

    Set-Variable -Name $d -Value $funcs -Scope Script -Force
  }
}

$buf, $ptr, $ptr_ = [Byte[]], [IntPtr], [IntPtr].MakeByRefType()

& $delegates kernel32 {
  bool CloseHandle([_ptr])
  bool DeviceIoControl([_ptr, uint, _buf, uint, _ptr, uint, _buf, _ptr])
}

& $delegates ntdll {
  void RtlInitUnicodeString([_buf, _buf])
  int  RtlNtStatusToDosError([int])
  int  NtCreateFile([_ptr_, int, _buf, _buf, _ptr, uint, uint, uint, uint, _ptr, uint])
}

$uni = [Byte[]]::new(($psz = [IntPtr]::Size) * 2) # UNICODE_STRING
$ntdll.RtlInitUnicodeString.Invoke($uni, [Encoding]::Unicode.GetBytes('\Device\Beep'))

$isb = [Byte[]]::new($psz * 2) # IO_STATUS_BLOCK (take but not check)
try {
  $gch = [GCHandle]::Alloc($uni, [GCHandleType]::Pinned)
  [Byte[]]$obj = [BitConverter]::GetBytes($psz * 6) + (
    ,0 * (4 + $psz) # OBJECT_ATTRIBUTES initialization
  ) + [BitConverter]::GetBytes(
    $gch.AddrOfPinnedObject().ToInt64()
  ) + (,0 * ($psz * 3))

  $hndl = [IntPtr]::Zero
  if (0 -ne ($nts = $ntdll.NtCreateFile.Invoke(
    [ref]$hndl, 0x80000000, $obj, $isb, [IntPtr]::Zero, 128, 1, 3, 0, [IntPtr]::Zero, 0
  ))) { throw [Win32Exception]::new($ntdll.RtlNtStatusToDosError.Invoke($nts)) }

  [Byte[]]$beep = [BitConverter]::GetBytes(1000) + [BitConverter]::GetBytes(700)
  $ret = [Byte[]]::new(4)
  [void]$kernel32.DeviceIoControl.Invoke(
    $hndl, (1 -shl 16), $beep, $beep.Length, [IntPtr]::Zero, 0, $ret, [IntPtr]::Zero
  )
}
catch { Write-Host $_ }
finally {
  if ($hndl -and $hndl -ne [IntPtr]::Zero) {
    if (!$kernel32.CloseHandle.Invoke($hndl)) { Write-Warning 'device has not been released.' }
  }

  if ($gch) { $gch.Free() }
}

Отправлено: 19:01, 23-03-2021 | #13