Beispiel #1
0
    """ Waits for the host to connect, and then says hello. """

    logging.info("Waiting for the host to connect.")
    await device.wait_for_host()
    logging.info("Host connected!")

    logging.info("Telling the user hello...")
    device.transmit("Hello! Welcome to the FTDI demo.\n")
    device.transmit(
        "Enter any text you'd like, and we'll send it back in UPPERCASE.\n")


def uppercasize(data):
    """ Convert any received data to uppercase. """

    # Convert the data to uppercase...
    uppercase = data.decode('utf-8').upper()

    # ... convert serial line endings to Python line endings...
    uppercase = uppercase.replace('\r', '\n')

    # ... and transmit our response.
    device.transmit(uppercase)


# Override the serial data handler by adding a singleton method on our object.
# This is an easy way to create one-off objects. :)
device.handle_serial_data_received = uppercasize

main(device, send_hello())
Beispiel #2
0
import logging

from facedancer import main
from facedancer.devices.keyboard import USBKeyboardDevice
from facedancer.classes.hid.keyboard import KeyboardModifiers

device = USBKeyboardDevice()


async def type_letters():
    logging.info("Beginning message typing demo...")

    # Type ls.
    await asyncio.sleep(5)
    await device.type_letters('l', 's', '\n')

    # Echo hi.
    await asyncio.sleep(2)
    await device.type_string("echo hi, user\n")

    # Finally, try to pop calc, just for fun.
    logging.info("Bonus: trying to pop calc.")
    await device.type_string('r', modifiers=KeyboardModifiers.MOD_LEFT_META)
    await asyncio.sleep(0.5)
    await device.type_string('calc\n')

    logging.info("Typing complete. Idly handling USB requests.")


main(device, type_letters())
Beispiel #3
0
    # theoretically do our reverse engineering, and then rename the request.
    #
    # Because the decorator indicates to the backend that this is a vendor
    # request handler, these names can be whatever we'd like -- and we don't
    # have to update anything when we change them!
    #
    @vendor_request_handler(number=15, direction=USBDirection.IN)
    @to_device
    def handle_get_version_request(self, request):
        # Most recent request was for 255B of data.

        # When hackrf_info gets to this point, we can see that it's
        # failing with "hackrf_version_string_read() failed: Pipe error (-1000)."
        #
        # That's a pretty good hint of what it expects.
        request.reply(b"Sekret FaceDancer Version")

    @vendor_request_handler(number=18, direction=USBDirection.IN)
    @to_device
    def handle_get_serial_request(self, request):
        # Most recent request was for 24B of data.
        request.reply(b'A' * 24)

    #
    # There's one last thing to do -- we'll need to implement one more
    # simple request. We'll leave this last one as an exercise to the reader. :)
    #


main(HackRF)
Beispiel #4
0
        # on the request.
        request.ack()

        # Of course, if we want to let the host know we can't handle a request, we
        # may also choose to stall it. This is as simple as calling request.stall().


    #
    # Note that request handlers can be used on configurations, interfaces, and
    # endpoints as well. For the latter two cases, the decorators `to_this_interface`
    # and `to_this_endpoint` are convenient -- they tell a request to run only if
    # it's directed at that endpoint in particular, as selected by its ``index`` parameter.
    #


# FaceDancer ships with a default main() function that you can use to set up and run
# your device. It ships with some nice features -- including a ``--suggest`` function
# that can suggest pieces of boilerplate code that might be useful in device emulation.
#
# main() will accept either the type of device to emulate, or an device instance.
# It'll also accept asyncio coroutines, in case you want to run things alongside the
# relevant device code. See e.g. `examples/rubber-ducky.py` for an example.
#
main(TemplateDevice)


#
# Of course, this template looks verbose as heck.
# For an example that's much less verbose, check out `examples/hackrf-info.py`.
#
Beispiel #5
0
        # The constructor arguments to each type accept the same fields as the declarative
        # API -- and like the declarative API, parameters have sane defaults...
        configuration = USBConfiguration()
        self.add_configuration(configuration)

        #  ... which means we don't really need to do much to create the various components.
        interface = USBInterface()
        configuration.add_interface(interface)

        # Like the declarative APIs, endpoints require a number and direction.
        out_endpoint = USBEndpoint(number=3, direction=USBDirection.OUT)
        interface.add_endpoint(out_endpoint)

    #
    # We'll still use our request decorators to declare request handlers
    # on the relevant objects...
    #
    @vendor_request_handler(number=13)
    def handle_my_request(self, request):
        request.acknowledge()

    #
    # ... and callbacks continue to work the same way.
    #
    def handle_data_received(self, endpoint, data):
        logging.info(f"New data: {data} on {endpoint}.")


main(ImperativeDevice())