Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare v1.1.0 Release #2

Merged
merged 7 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## v1.1.0 - July 17, 2024

### Added

* Add offset property to `RpcMethod`
* Add offset property to `SecurityCallback`

### Changed

* Fix type errors caused by newer v versions
* Fix incorrect attr syntax in newer v versions
* Fix incorrect address of security callbacks
* Rename `base` property of `RpcMethod` to `addr`
* Rename `base` property of `SecurityCallback` to `addr`


## v1.0.1 - Sep 24, 2023

### Changed
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[![](https://github.com/qtc-de/rpv/actions/workflows/build-examples.yml/badge.svg?branch=main)](https://github.com/qtc-de/rpv/actions/workflows/build-examples.yml)
[![](https://github.com/qtc-de/rpv/actions/workflows/build-examples.yml/badge.svg?branch=dev)](https://github.com/qtc-de/rpv/actions/workflows/build-examples.yml)
[![](https://img.shields.io/badge/version-1.0.1-blue)](https://github.com/qtc-de/rpv/releases)
[![](https://img.shields.io/badge/version-1.1.0-blue)](https://github.com/qtc-de/rpv/releases)
[![](https://img.shields.io/badge/programming%20language-v-blue)](https://vlang.io/)
[![](https://img.shields.io/badge/license-GPL%20v3.0-blue)](https://github.com/qtc-de/rpv/blob/master/LICENSE)
[![](https://img.shields.io/badge/docs-fa6b05)](https://qtc-de.github.io/rpv)
Expand All @@ -29,7 +29,7 @@ Assuming that *v* [is installed](https://github.com/vlang/v#installing-v-from-so
installing *rpv* can be done using the following command:

```console
[user@host ~]$ v install qtc_de.rpv
[user@host ~]$ v install qtc-de.rpv
```

After installation, *rpv* can be used to analyze *RPC* servers and
Expand Down
6 changes: 3 additions & 3 deletions alternate/default-x64.v
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub const compatible_rpc_versions = [
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcInterface {
pub:
p_rpc_server &RpcServer = unsafe { nil }
Expand Down Expand Up @@ -123,7 +123,7 @@ pub:
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcServer {
pub:
mutex Mutex
Expand Down Expand Up @@ -167,7 +167,7 @@ pub:
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcAddress {
pub:
vtable voidptr
Expand Down
6 changes: 3 additions & 3 deletions alternate/default-x86.v
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub const compatible_rpc_versions = [
// of v, the '[if x86]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x86]
@[if x86]
pub struct RpcInterface {
pub:
p_rpc_server &RpcServer = unsafe { nil }
Expand Down Expand Up @@ -119,7 +119,7 @@ pub:
// of v, the '[if x86]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x86]
@[if x86]
pub struct RpcServer {
pub:
mutex Mutex
Expand Down Expand Up @@ -158,7 +158,7 @@ pub:
// of v, the '[if x86]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x86]
@[if x86]
pub struct RpcAddress {
pub:
vtable voidptr
Expand Down
9 changes: 5 additions & 4 deletions examples/details.v
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ fn main()

println('[+] Security Callback:')

if intf.sec_callback.base != 0
if intf.sec_callback.addr != 0
{
println('[+]\t Registred : True')
println('[+]\t Base Address: 0x${intf.sec_callback.base}')
println('[+]\t Address : 0x${intf.sec_callback.addr}')
println('[+]\t Offset : 0x${intf.sec_callback.offset.hex()}')

if intf.sec_callback.location.path != ''
{
println('[+]\t Location : 0x${intf.sec_callback.location.path}')
println('[+]\t Location : ${intf.sec_callback.location.path}')
}
}

Expand All @@ -74,7 +75,7 @@ fn main()

for method in intf.methods
{
println('[+]\t ${method.name} (base: 0x${method.base})')
println('[+]\t ${method.name} (addr: 0x${method.addr}, offset: 0x${method.offset.hex()})')
}

return
Expand Down
2 changes: 2 additions & 0 deletions examples/list.v
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ fn main()
println('[+] Path : ${info.path}')

println('[+] RPC Endpoints:')

for endpoint in info.rpc_info.server_info.endpoints
{
println('[+]\t ${endpoint.protocol} - ${endpoint.name}')
}

println('[+] RPC Interfaces:')

for intf in info.rpc_info.interface_infos
{
if intf.methods.len > 0
Expand Down
28 changes: 14 additions & 14 deletions internals/rpc-common.v
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub:

// C.RPC_IF_ID represents an ID of an RPC interface. This is basically an GUID
// but also contains a major and minor version.
[typedef]
@[typedef]
pub struct C.RPC_IF_ID {
Uuid C.GUID
VersMajor u16
Expand All @@ -103,7 +103,7 @@ pub fn (this C.RPC_IF_ID) equals(other C.RPC_IF_ID) bool
// C.RPC_DISPATCH_TABLE contains information on the defined RPC methods of an
// RPC interface. rpv uses it to determine the method count, that can be obtained
// from the DispatchTableCount property.
[typedef]
@[typedef]
pub struct C.RPC_DISPATCH_TABLE {
DispatchTableCount u32
DispatchTable voidptr
Expand All @@ -116,7 +116,7 @@ pub struct C.RPC_DISPATCH_TABLE {
// formatting of these methods. This is used in conjunction with the FmtStringOffset
// property, which contains the offset of the different methods within the ProcString,
// to decompile RPC methods.
[typedef]
@[typedef]
pub struct C.MIDL_SERVER_INFO {
pStubDesc &C.MIDL_STUB_DESC = unsafe { nil }
DispatchTable &voidptr = unsafe { nil }
Expand All @@ -133,7 +133,7 @@ pub struct C.MIDL_SERVER_INFO {
// by the RPC methods of the corresponding interface. rpv uses this information to decompile
// RPC methods. Moreover, Reserved5 is required for parsing NDR expressions. Actually the
// member is named pExprInfo by Microsoft, but within the mingw libraries it is Reserved5.
[typedef]
@[typedef]
pub struct C.MIDL_STUB_DESC {
RpcInterfaceInformation voidptr = unsafe { nil }
pfnAllocate voidptr = unsafe { nil }
Expand All @@ -151,13 +151,13 @@ pub struct C.MIDL_STUB_DESC {
MIDLVersion u32
CommFaultOffsets &C.COMM_FAULT_OFFSETS = unsafe { nil }
// New fields for version 3.0+
aUserMarshalQuadruple &C.USER_MARSHAL_ROUTINE_QUADRUPLE = unsafe { nil }
aUserMarshalQuadruple voidptr = unsafe { nil }
// Notify routines - added for NT5, MIDL 5.0
NotifyRoutineTable &C.NDR_NOTIFY_ROUTINE = unsafe { nil }
NotifyRoutineTable voidptr = unsafe { nil }
// Reserved for future use.
mFlags &u32 = unsafe { nil }
// International support routines - added for 64bit post NT5
CsRoutineTables &C.NDR_CS_ROUTINES = unsafe { nil }
CsRoutineTables voidptr = unsafe { nil }
Reserved4 voidptr = unsafe { nil }
Reserved5 voidptr = unsafe { nil } // mIDA: expr_table - RpcView: pExprInfo
// Fields up to now present in win2000 release.
Expand All @@ -173,7 +173,7 @@ pub struct NDR_EXPR_DESC {

// C.MIDL_SYNTAX_INFO is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.MIDL_SYNTAX_INFO {
TransferSyntax C.RPC_SYNTAX_IDENTIFIER
DispatchTable &C.RPC_DISPATCH_TABLE
Expand All @@ -186,47 +186,47 @@ pub struct C.MIDL_SYNTAX_INFO {

// C.MIDL_INTERFACE_METHOD_PROPERTIES is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.MIDL_INTERFACE_METHOD_PROPERTIES {
MethodCount u16
MethodProperties &C.MIDL_METHOD_PROPERTY_MAP
}

// C.MIDL_METHOD_PROPERTY_MAP is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.MIDL_METHOD_PROPERTY_MAP {
count u32
Properties &C.MIDL_METHOD_PROPERTY
}

// C.MIDL_METHOD_PROPERTY is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.MIDL_METHOD_PROPERTY {
Id u32
value usize
}

// C.UUID_VECTOR is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.UUID_VECTOR {
Count u32
Uuid [1]&C.GUID
}

// C.RPC_SYNTAX_IDENTIFIER is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.RPC_SYNTAX_IDENTIFIER {
SyntaxGUID C.GUID
SyntaxVersion C.RPC_VERSION
}

// C.RPC_VERSION is a struct that is used within internal RPC struct definitions.
// It is currently not used by rpv.
[typedef]
@[typedef]
pub struct C.RPC_VERSION {
MajorVersion u16
MinorVersion u16
Expand Down
6 changes: 3 additions & 3 deletions internals/rpc-internal-structs.v
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub const compatible_rpc_versions = [
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcInterface {
pub:
p_rpc_server &RpcServer = unsafe { nil }
Expand Down Expand Up @@ -123,7 +123,7 @@ pub:
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcServer {
pub:
mutex Mutex
Expand Down Expand Up @@ -167,7 +167,7 @@ pub:
// of v, the '[if x64]' attribute is ignored for structs, but will be
// available in future. Up to this point, we need to keep the x64 and x86
// struct definitions in separate files.
[if x64]
@[if x64]
pub struct RpcAddress {
pub:
vtable voidptr
Expand Down
13 changes: 13 additions & 0 deletions ndr/context.v
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ pub struct NdrContext {
type_cache &TypeCache
}

// newNdrContext creates a new NdrContext. The main reason why we have a constructor
// here is to leave the struct fields access modifiers untouched. In newer v releases,
// initializing private struct fields seems only possible using a constructor.
pub fn NdrContext.new(handle win.HANDLE, stub_desc C.MIDL_STUB_DESC, flags NdrInterpreterOptFlags2, mut cache &TypeCache) NdrContext
{
return NdrContext {
process_handle: handle
stub_desc: stub_desc
flags: flags
type_cache: cache
}
}

// read attempts to read the type <T> from process memory at the specified
// address. If successfully, a newly created <T> type is returned. How many
// bytes to read is determined by the structure size of <T>. Notice that
Expand Down
4 changes: 2 additions & 2 deletions ndr/flags.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module ndr
// NdrFlags contains additional information for NDR data.
// Especially the has_return value is important for rpv,
// as it indicates whether a method returns a value.
[flag]
@[flag]
pub enum NdrFlags as u8
{
server_must_size
Expand All @@ -19,7 +19,7 @@ pub enum NdrFlags as u8
// NdrInterpreterOptFlags2 contains additional information
// on how to interpret NDR data. rpv needs this struct to
// determine how specific NDR types need to be parsed.
[flag]
@[flag]
pub enum NdrInterpreterOptFlags2 as u8
{
has_new_corr_desc
Expand Down
8 changes: 8 additions & 0 deletions ndr/ndr_basic.v
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ pub struct NdrSimpleType {
NdrBaseType
}

// new creates a new instance of NdrSimpleType. A constructor for this type was
// defined, because it is also initialized from other modules which are not able
// to access the private format property.
pub fn NdrSimpleType.new(format NdrFormatChar) NdrSimpleType
{
return NdrSimpleType { format: format }
}

// format returns the string representation of NdrSimpleType. This is always the
// same as the result of calling the format method on the underlying NdrBaseType.
pub fn (simple_type NdrSimpleType) format() string
Expand Down
2 changes: 1 addition & 1 deletion ndr/ndr_correlation.v
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub enum NdrCorrelationType as u8
// NdrCorrelationFlags provide additional information on a CorrelationDescriptor.
// As far as I remember, only the range member of this enum is currently used and
// implemented by rpv.
[flag]
@[flag]
pub enum NdrCorrelationFlags as u8
{
reserved
Expand Down
4 changes: 2 additions & 2 deletions ndr/ndr_param.v
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module ndr
// NdrHandleParam and to define a separate format method for both
// types. However, this caused nondeterministic memory corruptions.
// We may try this approach in future again.
[flag]
@[flag]
pub enum NdrParamAttrs as u16
{
must_size
Expand Down Expand Up @@ -103,7 +103,7 @@ pub fn (param NdrBasicParam) comments() []NdrComment
// NdrHandleParamFlags contains a list of flags that can be
// used in NdrHandleParam. These flags add more information
// to the underlying handle.
[flag]
@[flag]
pub enum NdrHandleParamFlags as u8
{
ndr_context_handle_cannot_be_null
Expand Down
14 changes: 13 additions & 1 deletion ndr/ndr_pointer.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import internals
// NdrPointerFlags contains a list of flags that can be set for
// NdrPointer types. These flags add additional information to
// the pointer that can be used during parsing and formatting.
[flag]
@[flag]
pub enum NdrPointerFlags as u8
{
fc_allocate_all_nodes
Expand All @@ -29,6 +29,18 @@ pub struct NdrPointer {
flags NdrPointerFlags
}

// new creates a new instance of NdrPointer. A constructor for this type was
// defined, because it is also initialized from other modules which are not able
// to access the private format property.
pub fn NdrPointer.new(format NdrFormatChar, ref NdrType, flags NdrPointerFlags) NdrPointer
{
return NdrPointer {
format: format
ref: ref
flags: flags
}
}

// attrs returns an array of NdrAttr that is associated to the
// NdrPointer type. This includes attributes that are associated
// to the pointer itself, as well as attributes that are associated
Expand Down
1 change: 1 addition & 0 deletions ndr/type_cache.v
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface ComplexType {
// decompilation, the types member contains all complex types that have
// been encountered within an interface. This allows easy formatting of
// decompilation results.
@[heap]
pub struct TypeCache {
mut:
type_map map[string]NdrType
Expand Down
Loading
Loading