From: Jay Freeman (saurik) Date: Fri, 16 Oct 2009 16:45:53 +0000 (+0000) Subject: I think this objectiriddification will finally stick. X-Git-Tag: v0.9.432~339 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/2c99abfef92b800edb3bcb08f6ed7a64d7c4ce39?ds=inline I think this objectiriddification will finally stick. --- diff --git a/Application.cpp b/Application.cpp new file mode 100644 index 0000000..725e246 --- /dev/null +++ b/Application.cpp @@ -0,0 +1,333 @@ +/* Cycript - Remove Execution Server and Disassembler + * Copyright (C) 2009 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + +#define _GNU_SOURCE + +#include +#include "cycript.hpp" + +#include +#include + +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include "Cycript.tab.hh" + +#include +#include +#include +#include + +static jmp_buf ctrlc_; + +static void sigint(int) { + longjmp(ctrlc_, 1); +} + +void Run(int socket, const char *data, size_t size, FILE *fout) { + CYPool pool; + + const char *json; + if (socket == -1) + json = CYExecute(pool, data); + else { + CYSendAll(socket, &size, sizeof(size)); + CYSendAll(socket, data, size); + CYRecvAll(socket, &size, sizeof(size)); + if (size == _not(size_t)) + json = NULL; + else { + char *temp(new(pool) char[size + 1]); + CYRecvAll(socket, temp, size); + temp[size] = '\0'; + json = temp; + } + } + + if (json != NULL && fout != NULL) { + fputs(json, fout); + fputs("\n", fout); + fflush(fout); + } +} + +void Run(int socket, std::string &code, FILE *fout) { + Run(socket, code.c_str(), code.size(), fout); +} + +static void Console(int socket) { + bool bypass(false); + bool debug(false); + + FILE *fout(stdout); + + rl_bind_key('\t', rl_insert); + + struct sigaction action; + sigemptyset(&action.sa_mask); + action.sa_handler = &sigint; + action.sa_flags = 0; + sigaction(SIGINT, &action, NULL); + + restart: for (;;) { + std::string command; + std::vector lines; + + bool extra(false); + const char *prompt("cy# "); + + if (setjmp(ctrlc_) != 0) { + fputs("\n", fout); + fflush(fout); + goto restart; + } + + read: + char *line(readline(prompt)); + if (line == NULL) + break; + + if (!extra) { + extra = true; + if (line[0] == '\\') { + std::string data(line + 1); + if (data == "bypass") { + bypass = !bypass; + fprintf(fout, "bypass == %s\n", bypass ? "true" : "false"); + fflush(fout); + } else if (data == "debug") { + debug = !debug; + fprintf(fout, "debug == %s\n", debug ? "true" : "false"); + fflush(fout); + } + add_history(line); + goto restart; + } + } + + lines.push_back(line); + command += line; + free(line); + + std::string code; + + if (bypass) + code = command; + else { + CYDriver driver(""); + cy::parser parser(driver); + + driver.data_ = command.c_str(); + driver.size_ = command.size(); + + if (parser.parse() != 0 || !driver.errors_.empty()) { + for (CYDriver::Errors::const_iterator error(driver.errors_.begin()); error != driver.errors_.end(); ++error) { + cy::position begin(error->location_.begin); + if (begin.line != lines.size() || begin.column - 1 != lines.back().size()) { + cy::position end(error->location_.end); + if (begin.line != lines.size()) { + std::cerr << " | "; + std::cerr << lines[begin.line - 1] << std::endl; + } + std::cerr << " | "; + for (size_t i(0); i != begin.column - 1; ++i) + std::cerr << '.'; + if (begin.line != end.line) + std::cerr << '^'; + else for (size_t i(0), e(end.column - begin.column); i != e; ++i) + std::cerr << '^'; + std::cerr << std::endl; + std::cerr << " | "; + std::cerr << error->message_ << std::endl; + add_history(command.c_str()); + goto restart; + } + } + + driver.errors_.clear(); + + command += '\n'; + prompt = "cy> "; + goto read; + } + + if (driver.source_ == NULL) + goto restart; + + if (socket != -1) + code = command; + else { + std::ostringstream str; + driver.source_->Show(str); + code = str.str(); + } + } + + add_history(command.c_str()); + + if (debug) + std::cout << code << std::endl; + + Run(socket, code, fout); + } + + fputs("\n", fout); + fflush(fout); +} + +static void *Map(const char *path, size_t *psize) { + int fd; + _syscall(fd = open(path, O_RDONLY)); + + struct stat stat; + _syscall(fstat(fd, &stat)); + size_t size(stat.st_size); + + *psize = size; + + void *base; + _syscall(base = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0)); + + _syscall(close(fd)); + return base; +} + +int main(int argc, char *argv[]) { + pid_t pid(_not(pid_t)); + + for (;;) switch (getopt(argc, argv, "p:")) { + case -1: + goto getopt; + case '?': + fprintf(stderr, "usage: cycript [-p ] [