/*
What's The Pointer?
By: Thomas Powers
An experiment in everything you're never supposed to do with pointers
This is a memory peek/poke program
You can browse memory as long as it's not a chunk of memory allocated to another app.
When you get pages of ?'s symbols that means that area of memory is inaccessible
Use the scan up (insert) or scan down (delete) key to search for the next block
of memory that is readable
You can use the 'w' key to alter the currently selected byte.
*/
#include <iostream>
#include <iomanip>
using namespace std;
#include <conio.h> // needed for the _getch() function
#include <windows.h>
#include <string>
#include <cmath>
const int ROWS=15;
const int COLS=16;
const int BLOCK_SIZE=ROWS*COLS;
void displayBlock(unsigned char *start, const unsigned char *homeAddr, unsigned int=0, unsigned int=0);
unsigned char *scan(unsigned char *, int);
void write(unsigned char *addr, unsigned int rowOffet=0, unsigned int colOffset=0);
enum COLOURS {
COLOUR_DEFAULT = 15,
COLOUR_HIGHLIGHT= 42,
COLOUR_OTHER = 14
};
enum KEYS {
ARROW_KEY = -32,
KEY_UP = 72,
KEY_DOWN = 80,
KEY_LEFT = 75,
KEY_RIGHT = 77,
HOME = 71,
PG_UP = 73,
PG_DOWN = 81,
INS = 82,
DEL = 83
};
const int LOW_INVALID_CHAR=7;
const int HIGH_INVALID_CHAR=13;
const string INVALID_CHAR_NAME[7]={"Bell", "Backspace", "Tab", "Line Feed", "Home", "Form Feed", "New Line"};
enum CHARS {
CHR_BELL = 7,
CHR_BACKSPACE = 8,
CHR_TAB = 9,
CHR_LINEFEED = 10,
CHR_HOME = 11,
CHR_FORMFEED = 12,
CHR_NEWLINE = 13
};
int main(int argc, char *argv[]) {
// this is our magic floating pointer (which is not a floating point, just a char)
unsigned char *p = new unsigned char;
// It might be interesting to start at a variable, focusing us somewhere in main's stackframe
// otherwise, just let p remain uninitialized
unsigned char s[]="[Welcome Home]";
// check the command line arguments
for ( int i=1; i < argc; i++ ) {
if ( strcmp(argv[i],"-mainframe")==0 ) {
p=s;
break;
}
if ( strcmp(argv[i],"-?")==0 ) {
cout << "Usage: To try to start you out near main()'s stack frame, use '-mainframe'\n"
<< "This will point to a local variable (a char array) in main()\n";
system("pause");
}
}
unsigned int selectRow=0, selectCol=0;
// make a copy of p so that we can always get back home
unsigned char *home=p;
char inp; // some place to get a key input from the user
// the main loop
do {
displayBlock(p,home,selectRow,selectCol);
inp=_getch();
if ( inp == ARROW_KEY ) {
// arrow keys, home, ins, del, etc.. actually give _getch() two chars
// if the first one was -32 we know this is happening
inp=_getch(); // read from the buffer the 2nd character (which arrow key?)
switch ( inp )
{
case KEY_RIGHT:
selectCol++;
selectCol%=COLS;
break;
case KEY_LEFT:
selectCol--;
selectCol%=COLS;
break;
case KEY_UP:
selectRow--;
selectRow%=ROWS;
break;
case KEY_DOWN:
selectRow++;
selectRow%=ROWS;
break;
case PG_UP:
p=p-BLOCK_SIZE;
break;
case PG_DOWN:
p=p+BLOCK_SIZE;
break;
case HOME:
p=home;
selectRow=0;
selectCol=0;
break;
case 88:
// uppercase X
cout << "\nGoodbye\n";
break;
case 120:
// lowercase x
cout << "\nGoodbye\n";
break;
case INS:
p=scan(p,-1);
break;
case DEL:
p=scan(p,1);
break;
}
} else {
// non arrow/control key
if ( inp == 'w' || inp == 'W' ) {
// write (poke)
write(p,selectRow,selectCol);
}
}
} while (inp != 'x' && inp != 'X');
return 0;
}
void displayBlock(unsigned char *start, const unsigned char *homeAddr, unsigned int selectRow, unsigned int selectCol) {
HANDLE hConsole;
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// set default color (white)
SetConsoleTextAttribute(hConsole,COLOUR_OTHER);
system ("cls");
cout << "Block starting at address: " << hex << long(start);
cout << " ("<< dec << long( fabs(double(start+selectCol+(selectRow*COLS)-homeAddr)) ) << " Bytes from home)";
cout << endl;
cout << "--------------------------------------------------------------------------------\n";
unsigned char chr[ROWS][COLS];
int r=0, c=0;
// read the block into a 2d array
for ( int i=0; i < BLOCK_SIZE; i++ ) {
// next row?
if ( i>0 && i%COLS==0 ) { r++; c=0; }
// try to get the byte from this location, otherwise use '?' if it's inaccessible memory
__try { chr[r][c]=start[i]; } __except ( true ) { chr[r][c]='?'; }
// next column
c++;
}
// display the array
for ( r=0; r < ROWS; r++ ) {
SetConsoleTextAttribute(hConsole,COLOUR_DEFAULT);
// print row address
cout << hex << long( start+(COLS*r) ) << " :";
// print hex values
for ( c=0; c < COLS; c++ ) {
cout << " "; // leading space, not highlighted
if ( r==selectRow && c==selectCol ) {
SetConsoleTextAttribute(hConsole,COLOUR_HIGHLIGHT); // highlight (inverted cyan)
} else {
SetConsoleTextAttribute(hConsole,COLOUR_DEFAULT); // white
}
cout << setw(2) << setfill('0') << hex << int(chr[r][c]);
SetConsoleTextAttribute(hConsole,15); // white
}
// print ascii characters
cout << " : ";
for ( c=0; c < COLS; c++ ) {
if ( r==selectRow && c==selectCol )
SetConsoleTextAttribute(hConsole,COLOUR_HIGHLIGHT); // highlight (inverted cyan)
else
SetConsoleTextAttribute(hConsole,COLOUR_DEFAULT); // white
// unless it's a character that's going to be a trouble maker
if ( chr[r][c] != NULL && ( chr[r][c] < LOW_INVALID_CHAR || chr[r][c] > HIGH_INVALID_CHAR ) ) {
cout << chr[r][c];
} else {
cout << ' ';
}
}
// new line, next row
cout << endl;
}
SetConsoleTextAttribute(hConsole,COLOUR_OTHER); // yellow
cout << "\n[Arrow Keys] select byte, [PG UP]/[PG DN] read previous/next block"
<< "\n[INS]/[DEL] Scan up/down, [HOME] starting location, [X] exit, [W] write\n";
cout << "\nSelected Byte: [";
if ( chr[selectRow][selectCol] != NULL && (
chr[selectRow][selectCol] < LOW_INVALID_CHAR ||
chr[selectRow][selectCol] > HIGH_INVALID_CHAR) )
{
cout << chr[selectRow][selectCol];
} else if ( chr[selectRow][selectCol] == NULL ) {
cout << "NULL";
} else {
cout << INVALID_CHAR_NAME[ chr[selectRow][selectCol] - LOW_INVALID_CHAR ];
}
cout << "] HEX:" << hex << int(chr[selectRow][selectCol]) << " Decimal: " << dec << int(chr[selectRow][selectCol]) << endl;
cout << "Address: " << hex << long( start+(selectCol)+(selectRow*COLS) );
SetConsoleTextAttribute(hConsole,COLOUR_DEFAULT);
}
unsigned char *scan(unsigned char *p, int direction) {
cout << "\nScanning for accessible memory, this may take... forever.....";
char chr=NULL;
bool readOK=false;
do {
__try {
chr=*p;
readOK=true;
} __except ( true ) {
p+=(BLOCK_SIZE*direction);
readOK=false;
}
} while ( !readOK );
return p;
}
void write(unsigned char *addr, unsigned int rowOffset, unsigned int colOffset)
{
unsigned int writeVal;
addr+=colOffset+(rowOffset*COLS);
cout << "\nEnter byte value (in decimal, 0-255, any invalid value (such as -1) will abort)\nByte Value: ";
cin >> writeVal;
if ( writeVal >=0 && writeVal <=255 ) {
__try {
*addr=char(writeVal);
} __except ( true ) {
cout << "\nWrite failed\n";
system("pause");
}
} else {
cout << "\nValue is invalid, aborting.\n";
system("pause");
}
}
C/C++改变控制台输出字体的背景和颜色(windows)
(2014-03-07 11:48:18)
可以用第二种方法改变部分字体的背景和颜色。
1. 全局设置
会改变整个窗口所有字体的背景和颜色。
system("color 04");
第一个数字代表背景色,第二个数字代表前景色。各颜色的代码如下:
0=黑色
1=蓝色
2=绿色
3=湖蓝色
4=红色
5=紫色
6=黄色
7=白色
8=灰色
9=淡蓝色
A=淡绿色
B=淡浅绿色
C=淡红色
D=淡紫色
E=淡黄色
F=亮白色
2. 改变下一个输出字体的背景和颜色
include
BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes);
hConsoleOutput: 设备句柄,通过GetStdHandle(STD_OUTPUT_HANDLE)获取。
wAttributes: 颜色属性
FOREGROUND_BLUE |
字体颜色:蓝 |
1 |
FOREGROUND_GREEN |
字体颜色:绿 |
2 |
FOREGROUND_RED |
字体颜色:红 |
4 |
FOREGROUND_INTENSITY |
前景色高亮显示 |
8 |
BACKGROUND_BLUE |
背景颜色:蓝 |
16 |
BACKGROUND_GREEN |
背景颜色:绿 |
32 |
BACKGROUND_RED |
背景颜色:红 |
64 |
BACKGROUND_INTENSITY |
背景色高亮显示 |
128 |
也就是说SetConsoleTextAttribute函数是靠一个字节的低四位控制前景色,高四位控制背景色。
例如白底红字可以写成:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY |FOREGROUND_INTENSITY | FOREGROUND_RED|BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
也可以写成:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xFC);
其他的颜色:
White on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
| FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
Red on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
|FOREGROUND_RED);
Green on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
| FOREGROUND_GREEN);
Yellow on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
|FOREGROUND_RED | FOREGROUND_GREEN);
Blue on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
|FOREGROUND_BLUE);
Magenta on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
|FOREGROUND_RED | FOREGROUND_BLUE);
Cyan on Black:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY
|FOREGROUND_GREEN | FOREGROUND_BLUE);
Black on White:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY
|FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
Red on White:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),BACKGROUND_INTENSITY
|FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
|FOREGROUND_RED);
例子:
#include
#include
int main()
{
HANDLE handle;
HANDLE = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);//设置为红色
printf("这是红色\n");
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY);//恢复默认的灰色
printf("这是灰色\n");
getch();
return 0;
}